protected boolean configDevice(DeviceId deviceId) {
        // Returns true if config was successful, false if not and a clean up is
        // needed.
        final Device device = deviceService.getDevice(deviceId);
        if (device == null || !device.is(IntProgrammable.class)) {
            return true;
        }

        if (isNotIntConfigured()) {
            log.warn("Missing INT config, aborting programming of INT device {}", deviceId);
            return true;
        }

        final boolean isEdge = !hostService.getConnectedHosts(deviceId).isEmpty();
        final IntDeviceRole intDeviceRole =
                isEdge ? IntDeviceRole.SOURCE_SINK : IntDeviceRole.TRANSIT;

        log.info("Started programming of INT device {} with role {}...",
                deviceId, intDeviceRole);

        final IntProgrammable intProg = device.as(IntProgrammable.class);

        if (!isIntStarted()) {
            // Leave device with no INT configuration.
            return true;
        }

        if (!intProg.init()) {
            log.warn("Unable to init INT pipeline on {}", deviceId);
            return false;
        }

        boolean supportSource = intProg.supportsFunctionality(IntProgrammable.IntFunctionality.SOURCE);
        boolean supportSink = intProg.supportsFunctionality(IntProgrammable.IntFunctionality.SINK);
        boolean supportPostcard = intProg.supportsFunctionality(IntProgrammable.IntFunctionality.POSTCARD);

        if (intDeviceRole != IntDeviceRole.SOURCE_SINK && !supportPostcard) {
            // Stop here, no more configuration needed for transit devices unless it support postcard.
            return true;
        }

        if (supportSink || supportPostcard) {
            if (!intProg.setupIntConfig(intConfig.get())) {
                log.warn("Unable to apply INT report config on {}", deviceId);
                return false;
            }
        }

        // Port configuration.
        final Set<PortNumber> hostPorts = deviceService.getPorts(deviceId)
                .stream()
                .map(port -> new ConnectPoint(deviceId, port.number()))
                .filter(cp -> !hostService.getConnectedHosts(cp).isEmpty())
                .map(ConnectPoint::port)
                .collect(Collectors.toSet());

        for (PortNumber port : hostPorts) {
            if (supportSource) {
                log.info("Setting port {}/{} as INT source port...", deviceId, port);
                if (!intProg.setSourcePort(port)) {
                    log.warn("Unable to set INT source port {} on {}", port, deviceId);
                    return false;
                }
            }
            if (supportSink) {
                log.info("Setting port {}/{} as INT sink port...", deviceId, port);
                if (!intProg.setSinkPort(port)) {
                    log.warn("Unable to set INT sink port {} on {}", port, deviceId);
                    return false;
                }
            }
        }

        if (!supportSource && !supportPostcard) {
            // Stop here, no more configuration needed for sink devices unless
            // it supports postcard mode.
            return true;
        }

        // Apply intents.
        // This is a trivial implementation where we simply get the
        // corresponding INT objective from an intent and we apply to all
        // device which support reporting.
        int appliedCount = 0;
        for (Versioned<IntIntent> versionedIntent : intentMap.values()) {
            IntIntent intent = versionedIntent.value();
            IntObjective intObjective = getIntObjective(intent);
            if (intent.telemetryMode() == IntIntent.TelemetryMode.INBAND_TELEMETRY && supportSource) {
                intProg.addIntObjective(intObjective);
                appliedCount++;
            } else if (intent.telemetryMode() == IntIntent.TelemetryMode.POSTCARD && supportPostcard) {
                intProg.addIntObjective(intObjective);
                appliedCount++;
            } else {
                log.warn("Device {} does not support intent {}.", deviceId, intent);
            }
        }
        log.info("Completed programming of {}, applied {} INT objectives of {} total",
                deviceId, appliedCount, intentMap.size());
        return true;
    }
@Test
    public void testConfigPostcardOnlyDevice() {
        reset(deviceService, hostService);
        Device device = getMockDevice(true, DEVICE_ID);
        IntProgrammable intProg = getMockIntProgrammable(false, false, false, true);
        setUpDeviceTest(device, intProg, true, true);
        IntObjective intObj = IntObjective.builder()
                .withSelector(FLOW_SELECTOR1)
                .build();
        expect(intProg.addIntObjective(eq(intObj)))
                .andReturn(true)
                .once();
        replay(deviceService, hostService, device, intProg);
        installTestIntents();
        assertTrue(manager.configDevice(DEVICE_ID));
        verify(intProg);
    }