HypervisorResource { @ApiOperation(notes = "Updates the list of Hypervisor Guests Allows agents such as " + "virt-who to update its host list and associate the guests for each host. This is " + "typically used when a host is unable to register to candlepin via subscription" + " manager. In situations where consumers already exist it is probably best not " + "to allow creation of new hypervisor consumers. Most consumers do not have a" + " hypervisorId attribute, so that should be added manually when necessary by the " + "management environment. @deprecated Use the asynchronous method", value = "hypervisorUpdate") @ApiResponses({ @ApiResponse(code = 202, message = "") }) @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Deprecated @Transactional @UpdateConsumerCheckIn @SuppressWarnings("checkstyle:indentation") public HypervisorUpdateResultDTO hypervisorUpdate( Map<String, List<GuestIdDTO>> hostGuestDTOMap, @Context Principal principal, @QueryParam("owner") @Verify(value = Owner.class, require = Access.READ_ONLY, subResource = SubResource.HYPERVISOR) String ownerKey, @ApiParam("specify whether or not to create missing hypervisors." + "Default is true. If false is specified, hypervisorIds that are not found" + "will result in failed entries in the resulting HypervisorCheckInResult") @QueryParam("create_missing") @DefaultValue("true") boolean createMissing) { log.debug("Hypervisor check-in by principal: {}", principal); if (hostGuestDTOMap == null) { log.debug("Host/Guest mapping provided during hypervisor checkin was null."); throw new BadRequestException( i18n.tr("Host to guest mapping was not provided for hypervisor check-in.")); } Owner owner = this.getOwner(ownerKey); if (hostGuestDTOMap.remove("") != null) { log.warn("Ignoring empty hypervisor id"); } VirtConsumerMap hypervisorConsumersMap = consumerCurator.getHostConsumersMap(owner, hostGuestDTOMap.keySet()); int emptyGuestIdCount = 0; Set<String> allGuestIds = new HashSet<>(); Collection<List<GuestIdDTO>> idsLists = hostGuestDTOMap.values(); for (List<GuestIdDTO> guestIds : idsLists) { if (guestIds == null) { continue; } for (Iterator<GuestIdDTO> guestIdsItr = guestIds.iterator(); guestIdsItr.hasNext();) { String id = guestIdsItr.next().getGuestId(); if (StringUtils.isEmpty(id)) { emptyGuestIdCount++; guestIdsItr.remove(); } else { allGuestIds.add(id); } } } if (emptyGuestIdCount > 0) { log.warn("Ignoring {} empty/null guest id(s).", emptyGuestIdCount); } HypervisorUpdateResultDTO result = new HypervisorUpdateResultDTO(); for (Entry<String, List<GuestIdDTO>> hostEntry : hostGuestDTOMap.entrySet()) { String hypervisorId = hostEntry.getKey(); if (hostEntry.getValue() == null) { hostEntry.setValue(new ArrayList<>()); } try { log.debug("Syncing virt host: {} ({} guest IDs)", hypervisorId, hostEntry.getValue().size()); boolean hostConsumerCreated = false; boolean updatedType = false; Consumer consumer = null; if (hypervisorConsumersMap.get(hypervisorId) == null) { if (!createMissing) { log.info("Unable to find hypervisor with id {} in org {}", hypervisorId, ownerKey); result.addFailed(hypervisorId, i18n.tr( "Unable to find hypervisor in org \"{0}\"", ownerKey)); continue; } log.debug("Registering new host consumer for hypervisor ID: {}", hypervisorId); consumer = createConsumerForHypervisorId(hypervisorId, owner, principal); hostConsumerCreated = true; } else { consumer = hypervisorConsumersMap.get(hypervisorId); if (!hypervisorType.getId().equals(consumer.getTypeId())) { consumer.setType(hypervisorType); updatedType = true; } } List<GuestId> guestIds = new ArrayList<>(); guestIdResource.populateEntities(guestIds, hostEntry.getValue()); boolean guestIdsUpdated = addGuestIds(consumer, guestIds); Date now = new Date(); consumerCurator.updateLastCheckin(consumer, now); consumer.setLastCheckin(now); if (hostConsumerCreated) { result.addCreated(this.translator.translate(consumer, HypervisorConsumerDTO.class)); } else if (guestIdsUpdated || updatedType) { result.addUpdated(this.translator.translate(consumer, HypervisorConsumerDTO.class)); } else { result.addUnchanged(this.translator.translate(consumer, HypervisorConsumerDTO.class)); } } catch (Exception e) { log.error("Hypervisor checkin failed", e); result.addFailed(hypervisorId, e.getMessage()); } } log.info("Summary of hypervisor checkin by principal \"{}\": {}", principal, result); return result; } @Inject  HypervisorResource(ConsumerResource consumerResource, ConsumerCurator consumerCurator,
        ConsumerTypeCurator consumerTypeCurator, I18n i18n, OwnerCurator ownerCurator,
        Provider<GuestMigration> migrationProvider, ModelTranslator translator,
        GuestIdResource guestIdResource, JobManager jobManager,
        @Named("HypervisorUpdateJobObjectMapper") final ObjectMapper mapper); @ApiOperation(notes = "Updates the list of Hypervisor Guests Allows agents such as " + "virt-who to update its host list and associate the guests for each host. This is " + "typically used when a host is unable to register to candlepin via subscription" + " manager. In situations where consumers already exist it is probably best not " + "to allow creation of new hypervisor consumers. Most consumers do not have a" + " hypervisorId attribute, so that should be added manually when necessary by the " + "management environment. @deprecated Use the asynchronous method", value = "hypervisorUpdate") @ApiResponses({ @ApiResponse(code = 202, message = "") }) @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Deprecated @Transactional @UpdateConsumerCheckIn @SuppressWarnings("checkstyle:indentation") HypervisorUpdateResultDTO hypervisorUpdate(
        Map<String, List<GuestIdDTO>> hostGuestDTOMap, @Context Principal principal,
        @QueryParam("owner") @Verify(value = Owner.class,
            require = Access.READ_ONLY,
            subResource = SubResource.HYPERVISOR) String ownerKey,
        @ApiParam("specify whether or not to create missing hypervisors." +
            "Default is true.  If false is specified, hypervisorIds that are not found" +
            "will result in failed entries in the resulting HypervisorCheckInResult")
        @QueryParam("create_missing") @DefaultValue("true") boolean createMissing); @ApiOperation(notes = "Creates or Updates the list of Hypervisor hosts Allows agents such" + " as virt-who to update hosts' information . This is typically used when a host is" + " unable to register to candlepin via subscription manager. In situations where " + "consumers already exist it is probably best not to allow creation of new hypervisor" + " consumers. Most consumers do not have a hypervisorId attribute, so that should be" + " added manually when necessary by the management environment. Default is true. " + "If false is specified, hypervisorIds that are not found will result in a failed " + "state of the job.", value = "hypervisorUpdateAsync") @ApiResponses({ @ApiResponse(code = 202, message = "") }) @POST @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.APPLICATION_JSON) @Path("/{owner}") @UpdateConsumerCheckIn @SuppressWarnings("checkstyle:indentation") AsyncJobStatusDTO hypervisorUpdateAsync(
        String hypervisorJson, @Context Principal principal,
        @PathParam("owner") @Verify(value = Owner.class,
            require = Access.READ_ONLY,
            subResource = SubResource.HYPERVISOR) String ownerKey,
        @ApiParam("specify whether or not to create missing hypervisors." +
            "Default is true.  If false is specified, hypervisorIds that are not found" +
            "will result in failed entries in the resulting HypervisorCheckInResult")

        @QueryParam("create_missing") @DefaultValue("true") boolean createMissing,
        @QueryParam("reporter_id") String reporterId); @ApiOperation(notes = "Updates last check in date of all consumers of the given reporterId.", value = "hypervisorHeartbeatUpdate") @ApiResponses({ @ApiResponse(code = 202, message = ""), @ApiResponse(code = 400, message = "Illegal reporter ID was provided"), @ApiResponse(code = 404, message = "Target owner not found.")}) @PUT @Consumes(MediaType.WILDCARD) @Produces(MediaType.APPLICATION_JSON) @Transactional @Path("/{owner}/heartbeat") AsyncJobStatusDTO hypervisorHeartbeatUpdate(
        @PathParam("owner")
        @Verify(value = Owner.class, require = Access.READ_ONLY, subResource = SubResource.HYPERVISOR)
        final String ownerKey,
        @QueryParam("reporter_id") final String reporterId);  }
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" }) @Test public void hypervisorCheckInReportsFailuresOnCreateFailure() throws Exception { Owner owner = new Owner("admin"); owner.setId("admin-id"); Map<String, List<GuestIdDTO>> hostGuestMap = new HashMap<>(); String expectedHostVirtId = "test-host-id"; hostGuestMap.put(expectedHostVirtId, new ArrayList(Arrays.asList(TestUtil.createGuestIdDTO("GUEST_A"), TestUtil.createGuestIdDTO("GUEST_B")))); when(consumerCurator.getHostConsumersMap(any(Owner.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(consumerCurator.getGuestConsumersMap(any(String.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(idCertService.generateIdentityCert(any(Consumer.class))) .thenReturn(new IdentityCertificate()); String expectedMessage = "Forced Exception."; RuntimeException exception = new RuntimeException(expectedMessage); when(ownerCurator.getByKey(eq(owner.getKey()))).thenReturn(owner); when(principal.canAccess(eq(owner), eq(SubResource.CONSUMERS), eq(Access.CREATE))). thenReturn(true); when(consumerCurator.create(any(Consumer.class))) .thenThrow(exception); HypervisorUpdateResultDTO result = hypervisorResource.hypervisorUpdate( hostGuestMap, principal, owner.getKey(), true); List<String> failures = new ArrayList<>(result.getFailedUpdate()); assertEquals(1, failures.size()); assertTrue(failures.get(0).contains("Problem creating unit")); }
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" }) @Test public void checkInCreatesNoNewConsumerWhenCreateIsFalse() throws Exception { Owner owner = new Owner("admin"); owner.setId("admin-id"); Map<String, List<GuestIdDTO>> hostGuestMap = new HashMap<>(); hostGuestMap.put("test-host", new ArrayList(Arrays.asList(TestUtil.createGuestIdDTO("GUEST_A"), TestUtil.createGuestIdDTO("GUEST_B")))); when(ownerCurator.getByKey(eq(owner.getKey()))).thenReturn(owner); when(consumerCurator.getHostConsumersMap(any(Owner.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(consumerCurator.getGuestConsumersMap(any(String.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(ownerCurator.getByKey(eq(owner.getKey()))).thenReturn(owner); when(principal.canAccess(eq(owner), eq(SubResource.CONSUMERS), eq(Access.CREATE))) .thenReturn(true); when(idCertService.generateIdentityCert(any(Consumer.class))) .thenReturn(new IdentityCertificate()); HypervisorUpdateResultDTO result = hypervisorResource.hypervisorUpdate( hostGuestMap, principal, owner.getKey(), false); assertNull(result.getCreated()); assertEquals(1, result.getFailedUpdate().size()); String failed = result.getFailedUpdate().iterator().next(); String expected = "test-host: Unable to find hypervisor in org \"admin\""; assertEquals(expected, failed); }
@SuppressWarnings("deprecation") @Test public void ensureBadRequestWhenNoMappingIsIncludedInRequest() { assertThrows(BadRequestException.class, () -> hypervisorResource.hypervisorUpdate(null, principal, "an-owner", false)); }
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" }) @Test public void ensureEmptyHypervisorIdsAreIgnored() throws Exception { Owner owner = new Owner("admin"); owner.setId("admin-id"); Map<String, List<GuestIdDTO>> hostGuestMap = new HashMap<>(); hostGuestMap.put("", new ArrayList(Arrays.asList(TestUtil.createGuestIdDTO("GUEST_A"), TestUtil.createGuestIdDTO("GUEST_B")))); hostGuestMap.put("HYPERVISOR_A", new ArrayList(Arrays.asList(TestUtil.createGuestIdDTO("GUEST_C"), TestUtil.createGuestIdDTO("GUEST_D")))); when(ownerCurator.getByKey(eq(owner.getKey()))).thenReturn(owner); when(ownerCurator.findOwnerById(any(String.class))).thenReturn(owner); when(consumerCurator.getHostConsumersMap(any(Owner.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(consumerCurator.getGuestConsumersMap(any(String.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(ownerCurator.getByKey(eq(owner.getKey()))).thenReturn(owner); when(principal.canAccess(eq(owner), eq(SubResource.CONSUMERS), eq(Access.CREATE))) .thenReturn(true); when(idCertService.generateIdentityCert(any(Consumer.class))) .thenReturn(new IdentityCertificate()); HypervisorUpdateResultDTO result = hypervisorResource.hypervisorUpdate( hostGuestMap, principal, owner.getKey(), true); assertNotNull(result); assertEquals(1, result.getCreated().size()); List<HypervisorConsumerDTO> created = new ArrayList<>(result.getCreated()); assertEquals("HYPERVISOR_A", created.get(0).getName()); }
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" }) @Test public void ensureEmptyGuestIdsAreIgnored() throws Exception { Owner owner = new Owner("admin"); owner.setId("test-id"); owner.setKey("test-key"); Map<String, List<GuestIdDTO>> hostGuestMap = new HashMap<>(); hostGuestMap.put("HYPERVISOR_A", new ArrayList( Arrays.asList(TestUtil.createGuestIdDTO("GUEST_A"), TestUtil.createGuestIdDTO("")))); when(ownerCurator.getByKey(eq(owner.getKey()))).thenReturn(owner); when(ownerCurator.findOwnerById(any(String.class))).thenReturn(owner); when(consumerCurator.getHostConsumersMap(any(Owner.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(consumerCurator.getGuestConsumersMap(any(String.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(ownerCurator.getByKey(eq(owner.getKey()))).thenReturn(owner); when(principal.canAccess(eq(owner), eq(SubResource.CONSUMERS), eq(Access.CREATE))) .thenReturn(true); when(idCertService.generateIdentityCert(any(Consumer.class))) .thenReturn(new IdentityCertificate()); HypervisorUpdateResultDTO result = hypervisorResource.hypervisorUpdate( hostGuestMap, principal, owner.getKey(), true); assertNotNull(result); assertNotNull(result.getCreated()); List<HypervisorConsumerDTO> created = new ArrayList<>(result.getCreated()); assertEquals(1, created.size()); assertEquals(1, hostGuestMap.get("HYPERVISOR_A").size()); assertEquals("GUEST_A", hostGuestMap.get("HYPERVISOR_A").get(0).getGuestId()); }
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" }) @Test public void treatNullGuestListsAsEmptyGuestLists() throws Exception { Owner owner = new Owner("admin"); owner.setId("test-id"); owner.setKey("test-key"); Map<String, List<GuestIdDTO>> hostGuestMap = new HashMap<>(); hostGuestMap.put("HYPERVISOR_A", null); when(ownerCurator.getByKey(eq(owner.getKey()))).thenReturn(owner); when(ownerCurator.findOwnerById(any(String.class))).thenReturn(owner); when(consumerCurator.getHostConsumersMap(any(Owner.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(consumerCurator.getGuestConsumersMap(any(String.class), any(Set.class))) .thenReturn(new VirtConsumerMap()); when(principal.canAccess(eq(owner), eq(SubResource.CONSUMERS), eq(Access.CREATE))) .thenReturn(true); when(idCertService.generateIdentityCert(any(Consumer.class))) .thenReturn(new IdentityCertificate()); HypervisorUpdateResultDTO result = hypervisorResource.hypervisorUpdate( hostGuestMap, principal, owner.getKey(), true); assertNotNull(result); assertNotNull(result.getCreated()); List<HypervisorConsumerDTO> created = new ArrayList<>(result.getCreated()); assertEquals(1, created.size()); assertEquals(0, hostGuestMap.get("HYPERVISOR_A").size()); }