You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jo...@apache.org on 2014/12/08 21:29:48 UTC

[25/51] [partial] incubator-nifi git commit: Initial code contribution

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/administration/src/test/java/org/apache/nifi/admin/service/action/SetUserAuthoritiesActionTest.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/administration/src/test/java/org/apache/nifi/admin/service/action/SetUserAuthoritiesActionTest.java b/nar-bundles/framework-bundle/framework/administration/src/test/java/org/apache/nifi/admin/service/action/SetUserAuthoritiesActionTest.java
new file mode 100644
index 0000000..dd3695c
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/administration/src/test/java/org/apache/nifi/admin/service/action/SetUserAuthoritiesActionTest.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.admin.service.action;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+import org.apache.nifi.admin.dao.AuthorityDAO;
+import org.apache.nifi.admin.dao.DAOFactory;
+import org.apache.nifi.admin.dao.UserDAO;
+import org.apache.nifi.admin.service.AccountNotFoundException;
+import org.apache.nifi.admin.service.AdministrationException;
+import org.apache.nifi.authorization.Authority;
+import org.apache.nifi.authorization.AuthorityProvider;
+import org.apache.nifi.authorization.exception.AuthorityAccessException;
+import org.apache.nifi.user.AccountStatus;
+import org.apache.nifi.user.NiFiUser;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+/**
+ * Test case for SetUserAuthoritiesAction.
+ */
+public class SetUserAuthoritiesActionTest {
+
+    private static final String USER_ID_1 = "1";
+    private static final String USER_ID_2 = "2";
+    private static final String USER_ID_3 = "3";
+
+    private static final String USER_DN_2 = "user dn 2";
+    private static final String USER_DN_3 = "user dn 3";
+
+    private DAOFactory daoFactory;
+    private UserDAO userDao;
+    private AuthorityDAO authorityDao;
+    private AuthorityProvider authorityProvider;
+
+    @Before
+    public void setup() throws Exception {
+        // mock the user dao
+        userDao = Mockito.mock(UserDAO.class);
+        Mockito.doAnswer(new Answer<NiFiUser>() {
+            @Override
+            public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                String id = (String) args[0];
+
+                NiFiUser user = null;
+                if (USER_ID_1.equals(id)) {
+                    // leave user uninitialized
+                } else if (USER_ID_2.equals(id)) {
+                    user = new NiFiUser();
+                    user.setId(USER_ID_2);
+                    user.setDn(USER_DN_2);
+                } else if (USER_ID_3.equals(id)) {
+                    user = new NiFiUser();
+                    user.setId(USER_ID_3);
+                    user.setDn(USER_DN_3);
+                    user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
+                    user.setStatus(AccountStatus.ACTIVE);
+                }
+                return user;
+            }
+        }).when(userDao).findUserById(Mockito.anyString());
+        Mockito.doAnswer(new Answer<NiFiUser>() {
+            @Override
+            public NiFiUser answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                String dn = (String) args[0];
+
+                NiFiUser user = null;
+                if (USER_DN_3.equals(dn)) {
+                    user = new NiFiUser();
+                    user.setId(USER_ID_3);
+                    user.setDn(USER_DN_3);
+                    user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_MONITOR));
+                    user.setStatus(AccountStatus.ACTIVE);
+                }
+                return user;
+            }
+        }).when(userDao).findUserByDn(Mockito.anyString());
+        Mockito.doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                NiFiUser user = (NiFiUser) args[0];
+
+                // do nothing
+                return null;
+            }
+        }).when(userDao).updateUser(Mockito.any(NiFiUser.class));
+
+        // mock the authority dao
+        authorityDao = Mockito.mock(AuthorityDAO.class);
+        Mockito.doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                Set<Authority> authorities = (Set<Authority>) args[0];
+                String id = (String) args[1];
+
+                // do nothing
+                return null;
+            }
+        }).when(authorityDao).createAuthorities(Mockito.anySetOf(Authority.class), Mockito.anyString());
+        Mockito.doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                Set<Authority> authorities = (Set<Authority>) args[0];
+                String id = (String) args[1];
+
+                // do nothing
+                return null;
+            }
+        }).when(authorityDao).deleteAuthorities(Mockito.anySetOf(Authority.class), Mockito.anyString());
+
+        // mock the dao factory
+        daoFactory = Mockito.mock(DAOFactory.class);
+        Mockito.when(daoFactory.getUserDAO()).thenReturn(userDao);
+        Mockito.when(daoFactory.getAuthorityDAO()).thenReturn(authorityDao);
+
+        // mock the authority provider
+        authorityProvider = Mockito.mock(AuthorityProvider.class);
+        Mockito.doAnswer(new Answer<Set<Authority>>() {
+            @Override
+            public Set<Authority> answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                String dn = (String) args[0];
+
+                Set<Authority> authorities = EnumSet.noneOf(Authority.class);
+                if (USER_DN_3.equals(dn)) {
+                    authorities.add(Authority.ROLE_DFM);
+                }
+
+                return authorities;
+            }
+        }).when(authorityProvider).getAuthorities(Mockito.anyString());
+        Mockito.doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                String dn = (String) args[0];
+                Set<Authority> authorites = (Set<Authority>) args[1];
+
+                if (USER_DN_2.equals(dn)) {
+                    throw new AuthorityAccessException(StringUtils.EMPTY);
+                }
+
+                // do nothing
+                return null;
+            }
+        }).when(authorityProvider).setAuthorities(Mockito.anyString(), Mockito.anySet());
+    }
+
+    /**
+     * Test activating an unknown user account. User accounts are unknown then
+     * there is no pending account for the user.
+     *
+     * @throws Exception
+     */
+    @Test(expected = AccountNotFoundException.class)
+    public void testUnknownUser() throws Exception {
+        UpdateUserAction setUserAuthorities = new UpdateUserAction(USER_ID_1, Collections.EMPTY_SET);
+        setUserAuthorities.execute(daoFactory, authorityProvider);
+    }
+
+    /**
+     * Testing case then an AuthorityAccessException occurs while setting a
+     * users authorities.
+     *
+     * @throws Exception
+     */
+    @Test(expected = AdministrationException.class)
+    public void testAuthorityAccessException() throws Exception {
+        UpdateUserAction setUserAuthorities = new UpdateUserAction(USER_ID_2, Collections.EMPTY_SET);
+        setUserAuthorities.execute(daoFactory, authorityProvider);
+    }
+
+    /**
+     * Tests general case of setting user authorities.
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testSetAuthorities() throws Exception {
+        UpdateUserAction setUserAuthorities = new UpdateUserAction(USER_ID_3, EnumSet.of(Authority.ROLE_ADMIN));
+        NiFiUser user = setUserAuthorities.execute(daoFactory, authorityProvider);
+
+        // verify user
+        Assert.assertEquals(USER_ID_3, user.getId());
+        Assert.assertEquals(1, user.getAuthorities().size());
+        Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_ADMIN));
+
+        // verify interaction with dao
+        Mockito.verify(userDao, Mockito.times(1)).updateUser(user);
+        Mockito.verify(authorityDao, Mockito.times(1)).createAuthorities(EnumSet.of(Authority.ROLE_ADMIN), USER_ID_3);
+
+        Set<Authority> authoritiesAddedToProvider = EnumSet.of(Authority.ROLE_ADMIN);
+
+        // verify interaction with provider
+        Mockito.verify(authorityProvider, Mockito.times(1)).setAuthorities(USER_DN_3, authoritiesAddedToProvider);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/administration/src/test/java/org/apache/nifi/admin/service/impl/NiFiAuthorizationServiceTest.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/administration/src/test/java/org/apache/nifi/admin/service/impl/NiFiAuthorizationServiceTest.java b/nar-bundles/framework-bundle/framework/administration/src/test/java/org/apache/nifi/admin/service/impl/NiFiAuthorizationServiceTest.java
new file mode 100644
index 0000000..5c8b75a
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/administration/src/test/java/org/apache/nifi/admin/service/impl/NiFiAuthorizationServiceTest.java
@@ -0,0 +1,284 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.admin.service.impl;
+
+import org.junit.Ignore;
+
+/**
+ *
+ */
+@Ignore
+public class NiFiAuthorizationServiceTest {
+
+//    private static final String UNKNOWN_USER_IN_CACHE_DN = "unknown-user-in-cache-dn";
+//    private static final String PENDING_USER_DN = "pending-user-dn";
+//    private static final String DISABLED_USER_DN = "disabled-user-dn";
+//    private static final String UNKNOWN_USER_IN_IDENTITY_PROVIDER_DN = "unknown-user-in-identity-provider-dn";
+//    private static final String ACCESS_EXCEPTION_IN_IDENTITY_PROVIDER_DN = "access-exception-in-identity-provider-dn";
+//    private static final String UNABLE_TO_UPDATE_CACHE_DN = "unable-to-update-cache-dn";
+//    private static final String VERIFICATION_REQUIRED_DN = "verification-required-dn";
+//    private static final String VERIFICATION_NOT_REQUIRED_DN = "verification-not-required-dn";
+//    private static final String NEW_USER_DN = "new-user-dn";
+//    
+//    private UserService userService;
+//    private AuthorityProvider authorityProvider;
+//    private UserDAO userDAO;
+//
+//    @Before
+//    public void setup() throws Exception {
+//        // mock the web security properties
+//        NiFiProperties properties = Mockito.mock(NiFiProperties.class);
+//        Mockito.when(properties.getSupportNewAccountRequests()).thenReturn(Boolean.TRUE);
+//        Mockito.when(properties.getUserCredentialCacheDurationSeconds()).thenReturn(60);
+//
+//        // mock the authority provider
+//
+//        // mock the admin service
+//        userDAO = Mockito.mock(UserDAO.class);
+//        Mockito.doAnswer(new Answer() {
+//
+//            @Override
+//            public Object answer(InvocationOnMock invocation) throws Throwable {
+//                Object[] args = invocation.getArguments();
+//                String dn = (String) args[0];
+//
+//                NiFiUser user = null;
+//                switch (dn) {
+//                    case PENDING_USER_DN:
+//                        user = new NiFiUser();
+//                        user.setDn(dn);
+//                        user.setStatus(AccountStatus.PENDING);
+//                        break;
+//                    case DISABLED_USER_DN:
+//                        user = new NiFiUser();
+//                        user.setDn(dn);
+//                        user.setStatus(AccountStatus.DISABLED);
+//                        break;
+//                    case UNKNOWN_USER_IN_IDENTITY_PROVIDER_DN:
+//                    case UNABLE_TO_UPDATE_CACHE_DN:
+//                    case ACCESS_EXCEPTION_IN_IDENTITY_PROVIDER_DN:
+//                        user = new NiFiUser();
+//                        user.setDn(dn);
+//                        user.setStatus(AccountStatus.ACTIVE);
+//                        break;
+//                    case VERIFICATION_REQUIRED_DN: {
+//                        Calendar calendar = Calendar.getInstance();
+//                        calendar.add(Calendar.SECOND, -65);
+//                        user = new NiFiUser();
+//                        user.setDn(dn);
+//                        user.setStatus(AccountStatus.ACTIVE);
+//                        user.setLastVerified(calendar.getTime());
+//                        user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_ADMIN, Authority.ROLE_DFM));
+//                        break;
+//                    }
+//                    case VERIFICATION_NOT_REQUIRED_DN: {
+//                        Calendar calendar = Calendar.getInstance();
+//                        calendar.add(Calendar.SECOND, -5);
+//                        user = new NiFiUser();
+//                        user.setDn(dn);
+//                        user.setStatus(AccountStatus.ACTIVE);
+//                        user.setLastVerified(calendar.getTime());
+//                        user.getAuthorities().addAll(EnumSet.of(Authority.ROLE_ADMIN, Authority.ROLE_DFM));
+//                        break;
+//                    }
+//                }
+//                return user;
+//            }
+//        }).when(userDAO).getUser(Mockito.anyString());
+//        Mockito.doAnswer(new Answer() {
+//
+//            @Override
+//            public Object answer(InvocationOnMock invocation) throws Throwable {
+//                Object[] args = invocation.getArguments();
+//                NiFiUser user = (NiFiUser) args[0];
+//
+//                if (UNABLE_TO_UPDATE_CACHE_DN.equals(user.getDn())) {
+//                    throw new AdministrationException();
+//                }
+//                return user;
+//            }
+//        }).when(userDAO).updateUser(Mockito.any(NiFiUser.class));
+//        Mockito.doNothing().when(userDAO).createUser(Mockito.any(NiFiUser.class));
+//
+//        // mock the authority provider
+//        authorityProvider = Mockito.mock(AuthorityProvider.class);
+//        Mockito.doAnswer(new Answer() {
+//
+//            @Override
+//            public Object answer(InvocationOnMock invocation) throws Throwable {
+//                Object[] args = invocation.getArguments();
+//                String dn = (String) args[0];
+//
+//                boolean hasDn = false;
+//                if (VERIFICATION_REQUIRED_DN.equals(dn) || NEW_USER_DN.equals(dn)) {
+//                    hasDn = true;
+//                }
+//                return hasDn;
+//            }
+//        }).when(authorityProvider).doesDnExist(Mockito.anyString());
+//        Mockito.doAnswer(new Answer() {
+//
+//            @Override
+//            public Object answer(InvocationOnMock invocation) throws Throwable {
+//                Object[] args = invocation.getArguments();
+//                String dn = (String) args[0];
+//
+//                Set<String> authorities = null;
+//                switch (dn) {
+//                    case VERIFICATION_REQUIRED_DN:
+//                    case NEW_USER_DN:
+//                        authorities = new HashSet<>();
+//                        authorities.add("ROLE_MONITOR");
+//                        break;
+//                    case DISABLED_USER_DN:
+//                        throw new UnknownIdentityException("Unable to find user");
+//                }
+//                return authorities;
+//            }
+//        }).when(authorityProvider).getAuthorities(Mockito.anyString());
+//
+//        // create an instance of the authorization service
+//        userService = new UserServiceImpl();
+//        ((UserServiceImpl) userService).setAuthorityProvider(authorityProvider);
+//        ((UserServiceImpl) userService).set(authorityProvider);
+//        
+////        authorizationService.setIdentityProvider(identityProvider);
+////        authorizationService.setAuthorityProvider(authorityProvider);
+////        authorizationService.setProperties(properties);
+//    }
+//
+//    /**
+//     * Ensures the authorization service correctly handles users who are
+//     * unknown.
+//     *
+//     * @throws Exception
+//     */
+//    @Test(expected = org.springframework.security.core.userdetails.UsernameNotFoundException.class)
+//    public void testUnknownUserInCache() throws Exception {
+//        authorizationService.loadUserByUsername(WebUtils.formatProxyDn(UNKNOWN_USER_IN_CACHE_DN));
+//    }
+//
+//    /**
+//     * Ensures the authorization service correctly handles users whose accounts
+//     * are PENDING.
+//     *
+//     * @throws Exception
+//     */
+//    @Test(expected = nifi.admin.service.AccountPendingException.class)
+//    public void testPendingUser() throws Exception {
+//        authorizationService.loadUserByUsername(WebUtils.formatProxyDn(PENDING_USER_DN));
+//    }
+//
+//    /**
+//     * Ensures the authorization service correctly handles users whose accounts
+//     * are DISABLED.
+//     *
+//     * @throws Exception
+//     */
+//    @Test(expected = org.springframework.security.authentication.DisabledException.class)
+//    public void testDisabledUser() throws Exception {
+//        authorizationService.loadUserByUsername(WebUtils.formatProxyDn(DISABLED_USER_DN));
+//    }
+//
+//    /**
+//     * Ensures the authorization service correctly handles users whose are in
+//     * the cache but have been removed from the identity provider.
+//     *
+//     * @throws Exception
+//     */
+//    @Test(expected = org.springframework.security.authentication.DisabledException.class)
+//    public void testUnknownUserInIdentityProvider() throws Exception {
+//        authorizationService.loadUserByUsername(WebUtils.formatProxyDn(UNKNOWN_USER_IN_IDENTITY_PROVIDER_DN));
+//    }
+//
+//    /**
+//     * Ensures the authorization service correctly handles cases when the cache
+//     * is unable to be updated.
+//     *
+//     * @throws Exception
+//     */
+//    @Test(expected = org.springframework.security.authentication.AuthenticationServiceException.class)
+//    public void testUnableToUpdateCache() throws Exception {
+//        authorizationService.loadUserByUsername(WebUtils.formatProxyDn(UNABLE_TO_UPDATE_CACHE_DN));
+//    }
+//
+//    /**
+//     * Ensures the authorization service correctly handles cases when the
+//     * identity provider has an access exception.
+//     *
+//     * @throws Exception
+//     */
+//    @Test(expected = org.springframework.security.authentication.AuthenticationServiceException.class)
+//    public void testUnableToAccessIdentity() throws Exception {
+//        authorizationService.loadUserByUsername(WebUtils.formatProxyDn(ACCESS_EXCEPTION_IN_IDENTITY_PROVIDER_DN));
+//    }
+//
+//    /**
+//     * Ensures that user authorities are properly loaded from the authority
+//     * provider.
+//     *
+//     * @throws Exception
+//     */
+//    @Test
+//    public void testVerificationRequiredUser() throws Exception {
+//        NiFiUserDetails userDetails = (NiFiUserDetails) authorizationService.loadUserByUsername(WebUtils.formatProxyDn(VERIFICATION_REQUIRED_DN));
+//        NiFiUser user = userDetails.getNiFiUser();
+//        Mockito.verify(authorityProvider).getAuthorities(VERIFICATION_REQUIRED_DN);
+//
+//        // ensure the user details
+//        Assert.assertEquals(VERIFICATION_REQUIRED_DN, user.getDn());
+//        Assert.assertEquals(1, user.getAuthorities().size());
+//        Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_MONITOR));
+//    }
+//
+//    /**
+//     * Ensures that user authorities are not loaded when the cache is still
+//     * valid.
+//     *
+//     * @throws Exception
+//     */
+//    @Test
+//    public void testVerificationNotRequiredUser() throws Exception {
+//        NiFiUserDetails userDetails = (NiFiUserDetails) authorizationService.loadUserByUsername(WebUtils.formatProxyDn(VERIFICATION_NOT_REQUIRED_DN));
+//        NiFiUser user = userDetails.getNiFiUser();
+//        Mockito.verify(authorityProvider, Mockito.never()).getAuthorities(VERIFICATION_NOT_REQUIRED_DN);
+//
+//        // ensure the user details
+//        Assert.assertEquals(VERIFICATION_NOT_REQUIRED_DN, user.getDn());
+//        Assert.assertEquals(2, user.getAuthorities().size());
+//        Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_ADMIN));
+//        Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_DFM));
+//    }
+//
+//    /**
+//     * Ensures that new users are automatically created when the authority
+//     * provider has their authorities.
+//     *
+//     * @throws Exception
+//     */
+//    @Test
+//    public void testNewUser() throws Exception {
+//        NiFiUserDetails userDetails = (NiFiUserDetails) authorizationService.loadUserByUsername(WebUtils.formatProxyDn(NEW_USER_DN));
+//        NiFiUser user = userDetails.getNiFiUser();
+//        Mockito.verify(authorityProvider).getAuthorities(NEW_USER_DN);
+//
+//        // ensure the user details
+//        Assert.assertEquals(NEW_USER_DN, user.getDn());
+//        Assert.assertEquals(1, user.getAuthorities().size());
+//        Assert.assertTrue(user.getAuthorities().contains(Authority.ROLE_MONITOR));
+//    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/.gitignore
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/.gitignore b/nar-bundles/framework-bundle/framework/client-dto/.gitignore
new file mode 100755
index 0000000..cd1a4e7
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/.gitignore
@@ -0,0 +1,6 @@
+/target
+/target
+/target
+/target
+/target
+/target

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/pom.xml
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/pom.xml b/nar-bundles/framework-bundle/framework/client-dto/pom.xml
new file mode 100644
index 0000000..4b210da
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.nifi</groupId>
+        <artifactId>nifi-framework-parent</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>client-dto</artifactId>
+    <name>NiFi Client Dto</name>
+    <build>
+        <plugins>
+            <!--
+                Always attach sources so the enunciate documentation
+                is complete.
+            -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>attach-sources</id>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>jar</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/AboutDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/AboutDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/AboutDTO.java
new file mode 100644
index 0000000..0e2dcb0
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/AboutDTO.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Contains details about this NiFi including the title and version.
+ */
+@XmlType(name = "about")
+public class AboutDTO {
+
+    private String title;
+    private String version;
+
+    /* getters / setters */
+    /**
+     * The title to be used on the page and in the About dialog.
+     *
+     * @return The title
+     */
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    /**
+     * The version of this NiFi.
+     *
+     * @return The version.
+     */
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BannerDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BannerDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BannerDTO.java
new file mode 100644
index 0000000..70c408b
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BannerDTO.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Banners that should appear on the top and bottom of this NiFi.
+ */
+@XmlType(name = "banners")
+public class BannerDTO {
+
+    private String headerText;
+    private String footerText;
+
+    /* getters / setters */
+    /**
+     * The banner footer text.
+     *
+     * @return The footer text
+     */
+    public String getFooterText() {
+        return footerText;
+    }
+
+    public void setFooterText(String footerText) {
+        this.footerText = footerText;
+    }
+
+    /**
+     * The banner header text.
+     *
+     * @return The header text
+     */
+    public String getHeaderText() {
+        return headerText;
+    }
+
+    public void setHeaderText(String headerText) {
+        this.headerText = headerText;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinBoardDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinBoardDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinBoardDTO.java
new file mode 100644
index 0000000..ddc3d2e
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinBoardDTO.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.Date;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
+
+/**
+ * The contents for the bulletin board including the bulletins and the timestamp
+ * when the board was generated.
+ */
+@XmlType(name = "bulletinBoard")
+public class BulletinBoardDTO {
+
+    private List<BulletinDTO> bulletins;
+    private Date generated;
+
+    /**
+     * The bulletins to populate in the bulletin board.
+     *
+     * @return
+     */
+    public List<BulletinDTO> getBulletins() {
+        return bulletins;
+    }
+
+    public void setBulletins(List<BulletinDTO> bulletins) {
+        this.bulletins = bulletins;
+    }
+
+    /**
+     * When this bulletin board was generated.
+     *
+     * @return
+     */
+    @XmlJavaTypeAdapter(TimeAdapter.class)
+    public Date getGenerated() {
+        return generated;
+    }
+
+    public void setGenerated(final Date generated) {
+        this.generated = generated;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinDTO.java
new file mode 100644
index 0000000..c6aca24
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinDTO.java
@@ -0,0 +1,161 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.Date;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
+
+/**
+ * A bulletin that represents a notification about a passing event including,
+ * the source component (if applicable), the timestamp, the message, and where
+ * the bulletin originated (if applicable).
+ */
+@XmlType(name = "bulletin")
+public class BulletinDTO {
+
+    private Long id;
+    private String nodeAddress;
+    private String category;
+    private String groupId;
+    private String sourceId;
+    private String sourceName;
+    private String level;
+    private String message;
+    private Date timestamp;
+
+    /**
+     * The id of this message.
+     *
+     * @return
+     */
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    /**
+     * When clustered, the address of the node from which this bulletin
+     * originated.
+     *
+     * @return
+     */
+    public String getNodeAddress() {
+        return nodeAddress;
+    }
+
+    public void setNodeAddress(String nodeAddress) {
+        this.nodeAddress = nodeAddress;
+    }
+
+    /**
+     * The group id of the source component.
+     *
+     * @return
+     */
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    /**
+     * The category of this message.
+     *
+     * @return
+     */
+    public String getCategory() {
+        return category;
+    }
+
+    public void setCategory(String category) {
+        this.category = category;
+    }
+
+    /**
+     * The actual message.
+     *
+     * @return
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    /**
+     * The id of the source of this message.
+     *
+     * @return
+     */
+    public String getSourceId() {
+        return sourceId;
+    }
+
+    public void setSourceId(String sourceId) {
+        this.sourceId = sourceId;
+    }
+
+    /**
+     * The name of the source of this message.
+     *
+     * @return
+     */
+    public String getSourceName() {
+        return sourceName;
+    }
+
+    public void setSourceName(String sourceName) {
+        this.sourceName = sourceName;
+    }
+
+    /**
+     * The level of this bulletin.
+     *
+     * @return
+     */
+    public String getLevel() {
+        return level;
+    }
+
+    public void setLevel(String level) {
+        this.level = level;
+    }
+
+    /**
+     * When this bulletin was generated as a formatted string.
+     *
+     * @return
+     */
+    @XmlJavaTypeAdapter(TimeAdapter.class)
+    public Date getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(Date timestamp) {
+        this.timestamp = timestamp;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinQueryDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinQueryDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinQueryDTO.java
new file mode 100644
index 0000000..015b174
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/BulletinQueryDTO.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * A query for bulletin board. Will filter the resulting bulletin board
+ * according to the criteria in this query.
+ */
+@XmlType(name = "bulletinQuery")
+public class BulletinQueryDTO {
+
+    private String sourceId;
+    private String groupId;
+    private String name;
+    private String message;
+    private Long after;
+    private Integer limit;
+
+    /**
+     * Include bulletins after this id.
+     *
+     * @return
+     */
+    public Long getAfter() {
+        return after;
+    }
+
+    public void setAfter(Long after) {
+        this.after = after;
+    }
+
+    /**
+     * Include bulletin within this group. Supports a regular expression.
+     *
+     * @return
+     */
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    /**
+     * Include bulletins that match this message. Supports a regular expression.
+     *
+     * @return
+     */
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    /**
+     * Include bulletins that match this name. Supports a regular expression.
+     *
+     * @return
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Include bulletins that match this id. Supports a source id.
+     *
+     * @return
+     */
+    public String getSourceId() {
+        return sourceId;
+    }
+
+    public void setSourceId(String sourceId) {
+        this.sourceId = sourceId;
+    }
+
+    /**
+     * The maximum number of bulletins to return.
+     *
+     * @return
+     */
+    public Integer getLimit() {
+        return limit;
+    }
+
+    public void setLimit(Integer limit) {
+        this.limit = limit;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ClusterDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ClusterDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ClusterDTO.java
new file mode 100644
index 0000000..53100e3
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ClusterDTO.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.Collection;
+import java.util.Date;
+
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
+
+/**
+ * Details about the composition of the cluster at a specific date/time.
+ */
+@XmlType(name = "cluster")
+public class ClusterDTO {
+
+    private Collection<NodeDTO> nodes;
+    private Date generated;
+
+    /**
+     * The collection of the node DTOs.
+     *
+     * @return
+     */
+    public Collection<NodeDTO> getNodes() {
+        return nodes;
+    }
+
+    public void setNodes(Collection<NodeDTO> nodes) {
+        this.nodes = nodes;
+    }
+
+    /**
+     * Gets the date/time that this report was generated.
+     *
+     * @return
+     */
+    @XmlJavaTypeAdapter(TimeAdapter.class)
+    public Date getGenerated() {
+        return generated;
+    }
+
+    public void setGenerated(Date generated) {
+        this.generated = generated;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectableDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectableDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectableDTO.java
new file mode 100644
index 0000000..1be480c
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectableDTO.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Details about a connectable component.
+ */
+@XmlType(name = "connectable")
+public class ConnectableDTO {
+
+    private String id;
+    private String type;
+    private String groupId;
+    private String name;
+    private Boolean running;
+    private Boolean transmitting;
+    private Boolean exists;
+    private String comments;
+
+    /**
+     * The id of this connectable component.
+     *
+     * @return
+     */
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * The type of this connectable component.
+     *
+     * @return
+     */
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * The id of the group that this connectable component resides in.
+     *
+     * @return
+     */
+    public String getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(String groupId) {
+        this.groupId = groupId;
+    }
+
+    /**
+     * The name of this connectable component.
+     *
+     * @return
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Used to reflect the current state of this Connectable.
+     *
+     * @return
+     */
+    public Boolean isRunning() {
+        return running;
+    }
+
+    public void setRunning(Boolean running) {
+        this.running = running;
+    }
+
+    /**
+     * If this represents a remote port it is used to indicate whether the
+     * target exists.
+     *
+     * @return
+     */
+    public Boolean getExists() {
+        return exists;
+    }
+
+    public void setExists(Boolean exists) {
+        this.exists = exists;
+    }
+
+    /**
+     * If this represents a remote port it is used to indicate whether is it
+     * configured to transmit.
+     *
+     * @return
+     */
+    public Boolean getTransmitting() {
+        return transmitting;
+    }
+
+    public void setTransmitting(Boolean transmitting) {
+        this.transmitting = transmitting;
+    }
+
+    /**
+     * The comments from this Connectable.
+     *
+     * @return
+     */
+    public String getComments() {
+        return comments;
+    }
+
+    public void setComments(String comments) {
+        this.comments = comments;
+    }
+
+    @Override
+    public String toString() {
+        return "ConnectableDTO [Type=" + type + ", Name=" + name + ", Id=" + id + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectionDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectionDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectionDTO.java
new file mode 100644
index 0000000..660820c
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ConnectionDTO.java
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.List;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * A connection between two connectable components.
+ */
+@XmlType(name = "connection")
+public class ConnectionDTO extends NiFiComponentDTO {
+
+    private ConnectableDTO source;
+    private ConnectableDTO destination;
+    private String name;
+    private Integer labelIndex;
+    private Long zIndex;
+    private Set<String> selectedRelationships;
+    private Set<String> availableRelationships;
+
+    private Long backPressureObjectThreshold;
+    private String backPressureDataSizeThreshold;
+    private String flowFileExpiration;
+    private List<String> prioritizers;
+    private List<PositionDTO> bends;
+
+    /**
+     * The id of the source processor.
+     *
+     * @return The id of the source processor
+     */
+    public ConnectableDTO getSource() {
+        return source;
+    }
+
+    public void setSource(ConnectableDTO source) {
+        this.source = source;
+    }
+
+    /**
+     * The id of the target processor.
+     *
+     * @return The id of the target processor
+     */
+    public ConnectableDTO getDestination() {
+        return destination;
+    }
+
+    public void setDestination(ConnectableDTO destination) {
+        this.destination = destination;
+    }
+
+    /**
+     * The name of the connection.
+     *
+     * @return
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * The position of the bend points on this connection.
+     *
+     * @return
+     */
+    public List<PositionDTO> getBends() {
+        return bends;
+    }
+
+    public void setBends(List<PositionDTO> bends) {
+        this.bends = bends;
+    }
+
+    /**
+     * The index of control point that the connection label should be placed
+     * over.
+     *
+     * @return
+     */
+    public Integer getLabelIndex() {
+        return labelIndex;
+    }
+
+    public void setLabelIndex(Integer labelIndex) {
+        this.labelIndex = labelIndex;
+    }
+
+    /**
+     * The z index for this connection.
+     *
+     * @return
+     */
+    public Long getzIndex() {
+        return zIndex;
+    }
+
+    public void setzIndex(Long zIndex) {
+        this.zIndex = zIndex;
+    }
+
+    /**
+     * The relationships that make up this connection.
+     *
+     * @return The relationships
+     */
+    public Set<String> getSelectedRelationships() {
+        return selectedRelationships;
+    }
+
+    public void setSelectedRelationships(Set<String> relationships) {
+        this.selectedRelationships = relationships;
+    }
+
+    /**
+     * The relationships that the source of the connection currently supports.
+     * This property is read only.
+     *
+     * @return
+     */
+    public Set<String> getAvailableRelationships() {
+        return availableRelationships;
+    }
+
+    public void setAvailableRelationships(Set<String> availableRelationships) {
+        this.availableRelationships = availableRelationships;
+    }
+
+    /**
+     * The object count threshold for determining when back pressure is applied.
+     * Updating this value is a passive change in the sense that it won't impact
+     * whether existing files over the limit are affected but it does help
+     * feeder processors to stop pushing too much into this work queue.
+     *
+     * @return The back pressure object threshold
+     */
+    public Long getBackPressureObjectThreshold() {
+        return backPressureObjectThreshold;
+    }
+
+    public void setBackPressureObjectThreshold(Long backPressureObjectThreshold) {
+        this.backPressureObjectThreshold = backPressureObjectThreshold;
+    }
+
+    /**
+     * The object data size threshold for determining when back pressure is
+     * applied. Updating this value is a passive change in the sense that it
+     * won't impact whether existing files over the limit are affected but it
+     * does help feeder processors to stop pushing too much into this work
+     * queue.
+     *
+     * @return The back pressure data size threshold
+     */
+    public String getBackPressureDataSizeThreshold() {
+        return backPressureDataSizeThreshold;
+    }
+
+    public void setBackPressureDataSizeThreshold(String backPressureDataSizeThreshold) {
+        this.backPressureDataSizeThreshold = backPressureDataSizeThreshold;
+    }
+
+    /**
+     * The amount of time a flow file may be in the flow before it will be
+     * automatically aged out of the flow. Once a flow file reaches this age it
+     * will be terminated from the flow the next time a processor attempts to
+     * start work on it.
+     *
+     * @return The flow file expiration in minutes
+     */
+    public String getFlowFileExpiration() {
+        return flowFileExpiration;
+    }
+
+    public void setFlowFileExpiration(String flowFileExpiration) {
+        this.flowFileExpiration = flowFileExpiration;
+    }
+
+    /**
+     * The prioritizers this processor is using.
+     *
+     * @return The prioritizer list
+     */
+    public List<String> getPrioritizers() {
+        return prioritizers;
+    }
+
+    public void setPrioritizers(List<String> prioritizers) {
+        this.prioritizers = prioritizers;
+    }
+
+    @Override
+    public String toString() {
+        return "ConnectionDTO [name: " + name + " from " + source + " to " + destination + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
new file mode 100644
index 0000000..b916025
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Details for the controller configuration.
+ */
+@XmlType(name = "config")
+public class ControllerConfigurationDTO {
+
+    private String name;
+    private String comments;
+    private Integer maxTimerDrivenThreadCount;
+    private Integer maxEventDrivenThreadCount;
+
+    private Long autoRefreshIntervalSeconds;
+    private Boolean siteToSiteSecure;
+
+    private Integer timeOffset;
+
+    private String contentViewerUrl;
+    private String uri;
+
+    /**
+     * The maximum number of timer driven threads this NiFi has available.
+     *
+     * @return The maximum number of threads
+     */
+    public Integer getMaxTimerDrivenThreadCount() {
+        return maxTimerDrivenThreadCount;
+    }
+
+    public void setMaxTimerDrivenThreadCount(Integer maxTimerDrivenThreadCount) {
+        this.maxTimerDrivenThreadCount = maxTimerDrivenThreadCount;
+    }
+
+    /**
+     * The maximum number of event driven thread this NiFi has available.
+     *
+     * @return
+     */
+    public Integer getMaxEventDrivenThreadCount() {
+        return maxEventDrivenThreadCount;
+    }
+
+    public void setMaxEventDrivenThreadCount(Integer maxEventDrivenThreadCount) {
+        this.maxEventDrivenThreadCount = maxEventDrivenThreadCount;
+    }
+
+    /**
+     * The name of this NiFi.
+     *
+     * @return The name
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * The comments for this NiFi.
+     *
+     * @return
+     */
+    public String getComments() {
+        return comments;
+    }
+
+    public void setComments(String comments) {
+        this.comments = comments;
+    }
+
+    /**
+     * The interval in seconds between the automatic NiFi refresh requests. This
+     * value is read only.
+     *
+     * @return The interval in seconds
+     */
+    public Long getAutoRefreshIntervalSeconds() {
+        return autoRefreshIntervalSeconds;
+    }
+
+    public void setAutoRefreshIntervalSeconds(Long autoRefreshIntervalSeconds) {
+        this.autoRefreshIntervalSeconds = autoRefreshIntervalSeconds;
+    }
+
+    /**
+     * Indicates whether or not Site-to-Site communications with this instance
+     * is secure (2-way authentication). This value is read only.
+     *
+     * @return
+     */
+    public Boolean isSiteToSiteSecure() {
+        return siteToSiteSecure;
+    }
+
+    public void setSiteToSiteSecure(Boolean siteToSiteSecure) {
+        this.siteToSiteSecure = siteToSiteSecure;
+    }
+
+    /**
+     * The time offset of the server.
+     *
+     * @return
+     */
+    public Integer getTimeOffset() {
+        return timeOffset;
+    }
+
+    public void setTimeOffset(Integer timeOffset) {
+        this.timeOffset = timeOffset;
+    }
+
+    /**
+     * Returns the URL for the content viewer if configured.
+     *
+     * @return
+     */
+    public String getContentViewerUrl() {
+        return contentViewerUrl;
+    }
+
+    public void setContentViewerUrl(String contentViewerUrl) {
+        this.contentViewerUrl = contentViewerUrl;
+    }
+
+    /**
+     * The URI for this NiFi controller.
+     *
+     * @return
+     */
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerDTO.java
new file mode 100644
index 0000000..9e15fc1
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerDTO.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.Set;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Configuration details for a NiFi controller. Primary use of this DTO is for
+ * consumption by a remote NiFi instance to initiate site to site
+ * communications.
+ */
+@XmlType(name = "controller")
+public class ControllerDTO {
+
+    private String id;
+    private String name;
+    private String comments;
+
+    private Integer runningCount;
+    private Integer stoppedCount;
+    private Integer invalidCount;
+    private Integer disabledCount;
+    private Integer activeRemotePortCount;
+    private Integer inactiveRemotePortCount;
+
+    private Integer inputPortCount;
+    private Integer outputPortCount;
+
+    private Integer remoteSiteListeningPort;
+    private Boolean siteToSiteSecure;
+    private String instanceId;
+    private Set<PortDTO> inputPorts;
+    private Set<PortDTO> outputPorts;
+
+    /**
+     * The id of this NiFi controller.
+     *
+     * @return
+     */
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * The name of this NiFi controller.
+     *
+     * @return The name of this controller
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * The comments of this NiFi controller.
+     *
+     * @return
+     */
+    public String getComments() {
+        return comments;
+    }
+
+    public void setComments(String comments) {
+        this.comments = comments;
+    }
+
+    /**
+     * The input ports available to send data to this NiFi controller.
+     *
+     * @return
+     */
+    public Set<PortDTO> getInputPorts() {
+        return inputPorts;
+    }
+
+    public void setInputPorts(Set<PortDTO> inputPorts) {
+        this.inputPorts = inputPorts;
+    }
+
+    /**
+     * The output ports available to received data from this NiFi controller.
+     *
+     * @return
+     */
+    public Set<PortDTO> getOutputPorts() {
+        return outputPorts;
+    }
+
+    public void setOutputPorts(Set<PortDTO> outputPorts) {
+        this.outputPorts = outputPorts;
+    }
+
+    /**
+     * The Instance ID of the cluster, if this node is connected to a Cluster
+     * Manager, or of this individual instance of in standalone mode
+     *
+     * @return
+     */
+    public String getInstanceId() {
+        return instanceId;
+    }
+
+    public void setInstanceId(String instanceId) {
+        this.instanceId = instanceId;
+    }
+
+    /**
+     * The Socket Port on which this instance is listening for Remote Transfers
+     * of Flow Files. If this instance is not configured to receive Flow Files
+     * from remote instances, this will be null.
+     *
+     * @return a integer between 1 and 65535, or null, if not configured for
+     * remote transfer
+     */
+    public Integer getRemoteSiteListeningPort() {
+        return remoteSiteListeningPort;
+    }
+
+    public void setRemoteSiteListeningPort(final Integer port) {
+        this.remoteSiteListeningPort = port;
+    }
+
+    /**
+     * Indicates whether or not Site-to-Site communications with this instance
+     * is secure (2-way authentication)
+     *
+     * @return
+     */
+    public Boolean isSiteToSiteSecure() {
+        return siteToSiteSecure;
+    }
+
+    public void setSiteToSiteSecure(Boolean siteToSiteSecure) {
+        this.siteToSiteSecure = siteToSiteSecure;
+    }
+
+    /**
+     * The number of running components in this process group.
+     *
+     * @return
+     */
+    public Integer getRunningCount() {
+        return runningCount;
+    }
+
+    public void setRunningCount(Integer runningCount) {
+        this.runningCount = runningCount;
+    }
+
+    /**
+     * The number of stopped components in this process group.
+     *
+     * @return
+     */
+    public Integer getStoppedCount() {
+        return stoppedCount;
+    }
+
+    public void setStoppedCount(Integer stoppedCount) {
+        this.stoppedCount = stoppedCount;
+    }
+
+    /**
+     * The number of active remote ports contained in this process group.
+     *
+     * @return
+     */
+    public Integer getActiveRemotePortCount() {
+        return activeRemotePortCount;
+    }
+
+    public void setActiveRemotePortCount(Integer activeRemotePortCount) {
+        this.activeRemotePortCount = activeRemotePortCount;
+    }
+
+    /**
+     * The number of inactive remote ports contained in this process group.
+     *
+     * @return
+     */
+    public Integer getInactiveRemotePortCount() {
+        return inactiveRemotePortCount;
+    }
+
+    public void setInactiveRemotePortCount(Integer inactiveRemotePortCount) {
+        this.inactiveRemotePortCount = inactiveRemotePortCount;
+    }
+
+    /**
+     * The number of input ports contained in this process group.
+     *
+     * @return
+     */
+    public Integer getInputPortCount() {
+        return inputPortCount;
+    }
+
+    public void setInputPortCount(Integer inputPortCount) {
+        this.inputPortCount = inputPortCount;
+    }
+
+    /**
+     * The number of invalid components in this process group.
+     *
+     * @return
+     */
+    public Integer getInvalidCount() {
+        return invalidCount;
+    }
+
+    public void setInvalidCount(Integer invalidCount) {
+        this.invalidCount = invalidCount;
+    }
+
+    /**
+     * The number of disabled components in this process group.
+     *
+     * @return
+     */
+    public Integer getDisabledCount() {
+        return disabledCount;
+    }
+
+    public void setDisabledCount(Integer disabledCount) {
+        this.disabledCount = disabledCount;
+    }
+
+    /**
+     * The number of output ports in this process group.
+     *
+     * @return
+     */
+    public Integer getOutputPortCount() {
+        return outputPortCount;
+    }
+
+    public void setOutputPortCount(Integer outputPortCount) {
+        this.outputPortCount = outputPortCount;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java
new file mode 100644
index 0000000..10ea41d
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/CounterDTO.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Counter value for a specific component in a specific context. A counter is a
+ * value that a component can adjust during processing.
+ */
+@XmlType(name = "counter")
+public class CounterDTO {
+
+    private String id;
+    private String context;
+    private String name;
+    private Long valueCount;
+    private String value;
+
+    /**
+     * The context of the counter.
+     *
+     * @return
+     */
+    public String getContext() {
+        return context;
+    }
+
+    public void setContext(String context) {
+        this.context = context;
+    }
+
+    /**
+     * The id of the counter.
+     *
+     * @return
+     */
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * The name of the counter
+     *
+     * @return
+     */
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * The value for the counter
+     *
+     * @return
+     */
+    public String getValue() {
+        return value;
+    }
+
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    public Long getValueCount() {
+        return valueCount;
+    }
+
+    public void setValueCount(Long valueCount) {
+        this.valueCount = valueCount;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java
new file mode 100644
index 0000000..ac1aa38
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/CountersDTO.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.Collection;
+import java.util.Date;
+
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.apache.nifi.web.api.dto.util.TimeAdapter;
+
+/**
+ * All the counters in this NiFi instance at a given time.
+ */
+@XmlType(name = "counters")
+public class CountersDTO {
+
+    private Date generated;
+    private Collection<CounterDTO> counters;
+
+    /**
+     * Gets the collection of counters.
+     *
+     * @return
+     */
+    public Collection<CounterDTO> getCounters() {
+        return counters;
+    }
+
+    public void setCounters(Collection<CounterDTO> counters) {
+        this.counters = counters;
+    }
+
+    /**
+     * Gets the date/time that this report was generated.
+     *
+     * @return
+     */
+    @XmlJavaTypeAdapter(TimeAdapter.class)
+    public Date getGenerated() {
+        return generated;
+    }
+
+    public void setGenerated(Date generated) {
+        this.generated = generated;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/DocumentedTypeDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/DocumentedTypeDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/DocumentedTypeDTO.java
new file mode 100644
index 0000000..5a2d789
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/DocumentedTypeDTO.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.Set;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Class used for providing documentation of a specified type that may be
+ * instantiated.
+ */
+@XmlType(name = "documentedType")
+public class DocumentedTypeDTO {
+
+    private String type;
+    private String description;
+    private Set<String> tags;
+
+    /**
+     * An optional description of the corresponding type.
+     *
+     * @return
+     */
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    /**
+     * The type is the fully-qualified name of a Java class.
+     *
+     * @return
+     */
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    /**
+     * The tags associated with this type
+     *
+     * @return
+     */
+    public Set<String> getTags() {
+        return tags;
+    }
+
+    public void setTags(final Set<String> tags) {
+        this.tags = tags;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowSnippetDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowSnippetDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowSnippetDTO.java
new file mode 100644
index 0000000..61c3c33
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowSnippetDTO.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * The contents of a flow snippet.
+ */
+@XmlType(name = "flowSnippet")
+public class FlowSnippetDTO {
+
+    private Set<ProcessGroupDTO> processGroups = new LinkedHashSet<>();
+    private Set<RemoteProcessGroupDTO> remoteProcessGroups = new LinkedHashSet<>();
+    private Set<ProcessorDTO> processors = new LinkedHashSet<>();
+    private Set<PortDTO> inputPorts = new LinkedHashSet<>();
+    private Set<PortDTO> outputPorts = new LinkedHashSet<>();
+    private Set<ConnectionDTO> connections = new LinkedHashSet<>();
+    private Set<LabelDTO> labels = new LinkedHashSet<>();
+    private Set<FunnelDTO> funnels = new LinkedHashSet<>();
+
+    /**
+     * The connections in this flow snippet.
+     *
+     * @return
+     */
+    public Set<ConnectionDTO> getConnections() {
+        return connections;
+    }
+
+    public void setConnections(Set<ConnectionDTO> connections) {
+        this.connections = connections;
+    }
+
+    /**
+     * The input ports in this flow snippet.
+     *
+     * @return
+     */
+    public Set<PortDTO> getInputPorts() {
+        return inputPorts;
+    }
+
+    public void setInputPorts(Set<PortDTO> inputPorts) {
+        this.inputPorts = inputPorts;
+    }
+
+    /**
+     * The labels in this flow snippet.
+     *
+     * @return
+     */
+    public Set<LabelDTO> getLabels() {
+        return labels;
+    }
+
+    public void setLabels(Set<LabelDTO> labels) {
+        this.labels = labels;
+    }
+
+    /**
+     * The funnels in this flow snippet.
+     *
+     * @return
+     */
+    public Set<FunnelDTO> getFunnels() {
+        return funnels;
+    }
+
+    public void setFunnels(Set<FunnelDTO> funnels) {
+        this.funnels = funnels;
+    }
+
+    /**
+     * The output ports in this flow snippet.
+     *
+     * @return
+     */
+    public Set<PortDTO> getOutputPorts() {
+        return outputPorts;
+    }
+
+    public void setOutputPorts(Set<PortDTO> outputPorts) {
+        this.outputPorts = outputPorts;
+    }
+
+    /**
+     * The process groups in this flow snippet.
+     *
+     * @return
+     */
+    public Set<ProcessGroupDTO> getProcessGroups() {
+        return processGroups;
+    }
+
+    public void setProcessGroups(Set<ProcessGroupDTO> processGroups) {
+        this.processGroups = processGroups;
+    }
+
+    /**
+     * The processors in this flow group.
+     *
+     * @return
+     */
+    public Set<ProcessorDTO> getProcessors() {
+        return processors;
+    }
+
+    public void setProcessors(Set<ProcessorDTO> processors) {
+        this.processors = processors;
+    }
+
+    /**
+     * The remote process groups in this flow snippet.
+     *
+     * @return
+     */
+    public Set<RemoteProcessGroupDTO> getRemoteProcessGroups() {
+        return remoteProcessGroups;
+    }
+
+    public void setRemoteProcessGroups(Set<RemoteProcessGroupDTO> remoteProcessGroups) {
+        this.remoteProcessGroups = remoteProcessGroups;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/FunnelDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/FunnelDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/FunnelDTO.java
new file mode 100644
index 0000000..1240501
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/FunnelDTO.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Details of a funnel.
+ */
+@XmlType(name = "funnel")
+public class FunnelDTO extends NiFiComponentDTO {
+
+    public FunnelDTO() {
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/LabelDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/LabelDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/LabelDTO.java
new file mode 100644
index 0000000..f50c792
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/LabelDTO.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import java.util.Collections;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Details of a label.
+ */
+@XmlType(name = "label")
+public class LabelDTO extends NiFiComponentDTO {
+
+    private String label;
+
+    private Double width;
+    private Double height;
+
+    // font-size = 12px
+    // color = #eee
+    private Map<String, String> style = Collections.emptyMap();
+
+    public LabelDTO() {
+    }
+
+    /**
+     * The text that appears in the label.
+     *
+     * @return The label text
+     */
+    public String getLabel() {
+        return label;
+    }
+
+    public void setLabel(final String label) {
+        this.label = label;
+    }
+
+    /**
+     * The style for this label.
+     *
+     * @return
+     */
+    public Map<String, String> getStyle() {
+        return style;
+    }
+
+    public void setStyle(Map<String, String> style) {
+        this.style = style;
+    }
+
+    /**
+     * The height of the label in pixels when at a 1:1 scale.
+     *
+     * @return
+     */
+    public Double getHeight() {
+        return height;
+    }
+
+    public void setHeight(Double height) {
+        this.height = height;
+    }
+
+    /**
+     * The width of the label in pixels when at a 1:1 scale.
+     *
+     * @return
+     */
+    public Double getWidth() {
+        return width;
+    }
+
+    public void setWidth(Double width) {
+        this.width = width;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/4d998c12/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/NiFiComponentDTO.java
----------------------------------------------------------------------
diff --git a/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/NiFiComponentDTO.java b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/NiFiComponentDTO.java
new file mode 100644
index 0000000..e3c8445
--- /dev/null
+++ b/nar-bundles/framework-bundle/framework/client-dto/src/main/java/org/apache/nifi/web/api/dto/NiFiComponentDTO.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.nifi.web.api.dto;
+
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Base class for all nifi components.
+ */
+@XmlType(name = "nifiComponent")
+public class NiFiComponentDTO {
+
+    private String id;
+    private String uri;
+    private PositionDTO position;
+    private String parentGroupId;
+
+    public NiFiComponentDTO() {
+    }
+
+    public NiFiComponentDTO(final String id) {
+        this.id = id;
+    }
+
+    public NiFiComponentDTO(final String id, final double x, final double y) {
+        this.id = id;
+        this.position = new PositionDTO(x, y);
+    }
+
+    /**
+     * The id for this component.
+     *
+     * @return The id
+     */
+    public String getId() {
+        return this.id;
+    }
+
+    public void setId(final String id) {
+        this.id = id;
+    }
+
+    /**
+     * The id for the parent group of this component.
+     *
+     * @return
+     */
+    public String getParentGroupId() {
+        return parentGroupId;
+    }
+
+    public void setParentGroupId(String parentGroupId) {
+        this.parentGroupId = parentGroupId;
+    }
+
+    /**
+     * The uri for linking to this component in this NiFi.
+     *
+     * @return The uri
+     */
+    public String getUri() {
+        return uri;
+    }
+
+    public void setUri(String uri) {
+        this.uri = uri;
+    }
+
+    public void setPosition(final PositionDTO position) {
+        this.position = position;
+    }
+
+    /**
+     * The position of this component in the UI.
+     *
+     * @return The position
+     */
+    public PositionDTO getPosition() {
+        return position;
+    }
+}