Skip to content

Commit 2f0cce9

Browse files
authored
Support publishing with submodules (#984)
* Fix LocalAppEngineServerBehaviour to handle module paths * Leverage Tomcat's PublishOperation * Make all publish methods protected to allow overriding
1 parent 016a8ea commit 2f0cce9

File tree

29 files changed

+1443
-137
lines changed

29 files changed

+1443
-137
lines changed

features/com.google.cloud.tools.eclipse.suite.e45.feature/feature.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,11 @@
155155
fragment="true"
156156
unpack="false"/>
157157

158+
<plugin
159+
id="com.google.cloud.tools.eclipse.jst.server.core"
160+
download-size="0"
161+
install-size="0"
162+
version="0.0.0"
163+
unpack="false"/>
164+
158165
</feature>

plugins/com.google.cloud.tools.eclipse.appengine.facets.test/META-INF/MANIFEST.MF

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ Fragment-Host: com.google.cloud.tools.eclipse.appengine.facets
1010
Require-Bundle: org.hamcrest;bundle-version="1.1.0",
1111
org.junit;bundle-version="4.12.0",
1212
org.eclipse.wst.common.project.facet.core
13-
Import-Package: org.eclipse.core.resources,
13+
Import-Package: com.google.cloud.tools.eclipse.test.util.project,
14+
org.eclipse.core.resources,
1415
org.eclipse.wst.common.project.facet.core,
1516
org.mockito;provider=google;version="1.10.19",
1617
org.mockito.runners;provider=google;version="1.10.19",

plugins/com.google.cloud.tools.eclipse.appengine.facets.test/src/com/google/cloud/tools/eclipse/appengine/facets/StandardFacetsInstallationTests.java

Lines changed: 12 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,31 @@
1616

1717
package com.google.cloud.tools.eclipse.appengine.facets;
1818

19+
import static org.junit.Assert.assertEquals;
1920
import static org.junit.Assert.assertFalse;
20-
import static org.junit.Assert.assertNotNull;
2121
import static org.junit.Assert.assertTrue;
2222

23+
import com.google.cloud.tools.eclipse.test.util.project.ProjectUtils;
2324
import com.google.cloud.tools.eclipse.util.FacetedProjectHelper;
24-
import java.io.File;
2525
import java.io.IOException;
26-
import java.net.URL;
27-
import java.util.zip.ZipFile;
26+
import java.util.List;
2827
import org.eclipse.core.resources.IFile;
2928
import org.eclipse.core.resources.IProject;
30-
import org.eclipse.core.resources.IProjectDescription;
3129
import org.eclipse.core.resources.IWorkspaceRoot;
3230
import org.eclipse.core.resources.ResourcesPlugin;
3331
import org.eclipse.core.runtime.CoreException;
34-
import org.eclipse.core.runtime.FileLocator;
35-
import org.eclipse.core.runtime.IPath;
3632
import org.eclipse.core.runtime.Path;
37-
import org.eclipse.core.runtime.SubMonitor;
3833
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
39-
import org.eclipse.wst.common.project.facet.core.util.internal.ZipUtil;
4034
import org.junit.After;
4135
import org.junit.Before;
4236
import org.junit.Test;
43-
import org.osgi.framework.Bundle;
44-
import org.osgi.framework.FrameworkUtil;
4537

4638
/**
4739
* Tests some cases of installing the App Engine Standard facet on existing projects.
4840
*/
4941
public class StandardFacetsInstallationTests {
5042
private IWorkspaceRoot root;
51-
private IProject project;
43+
private List<IProject> projects;
5244

5345
@Before
5446
public void setUp() {
@@ -57,14 +49,19 @@ public void setUp() {
5749

5850
@After
5951
public void tearDown() throws CoreException {
60-
if (project != null) {
61-
project.delete(true, null);
52+
if (projects != null) {
53+
for (IProject project : projects) {
54+
project.delete(true, null);
55+
}
6256
}
6357
}
6458

6559
@Test
6660
public void testStandardFacetInstallationOnGwtWar() throws IOException, CoreException {
67-
project = importProject("projects/test-dynamic-web-project.zip");
61+
projects =
62+
ProjectUtils.importProjects(getClass(), "projects/test-dynamic-web-project.zip", null);
63+
assertEquals(1, projects.size());
64+
IProject project = projects.get(0);
6865
IFacetedProject facetedProject = new FacetedProjectHelper().getFacetedProject(project);
6966
// verify that the appengine-web.xml is installed in the dynamic web root folder
7067
AppEngineStandardFacet.installAppEngineFacet(facetedProject, true, null);
@@ -74,37 +71,4 @@ public void testStandardFacetInstallationOnGwtWar() throws IOException, CoreExce
7471
assertTrue(correctAppEngineWebXml.exists());
7572
assertFalse(wrongAppEngineWebXml.exists());
7673
}
77-
78-
private IProject importProject(String relativeLocation) throws IOException, CoreException {
79-
SubMonitor progress = SubMonitor.convert(null, 13);
80-
// Resolve the zip'd project within this bundle
81-
Bundle bundle = FrameworkUtil.getBundle(getClass());
82-
URL bundleLocation = bundle.getResource(relativeLocation);
83-
assertNotNull(bundleLocation);
84-
URL zipLocation = FileLocator.toFileURL(bundleLocation);
85-
if (!zipLocation.getProtocol().equals("file")) {
86-
throw new IOException("could not resolve location to a file");
87-
}
88-
File zippedFile = new File(zipLocation.getPath());
89-
assertTrue(zippedFile.exists());
90-
progress.worked(1);
91-
92-
// extract project into our workspace using WTP internal utility class
93-
ZipUtil.unzip(zippedFile, root.getLocation().toFile(), progress.newChild(2));
94-
95-
// determine the project location; a bit of a hack as we assume the
96-
// first entry is the directory, but which seems to hold for all zips
97-
String dirRoot;
98-
try (ZipFile zip = new ZipFile(zippedFile)) {
99-
dirRoot = zip.entries().nextElement().getName();
100-
}
101-
// import the project
102-
IPath projectFileLocation = root.getLocation().append(new Path(dirRoot + ".project"));
103-
IProjectDescription descriptor =
104-
root.getWorkspace().loadProjectDescription(projectFileLocation);
105-
IProject project = root.getProject(descriptor.getName());
106-
project.create(descriptor, progress.newChild(5)); // adds the project to the workspace
107-
project.open(progress.newChild(5)); // opens the project
108-
return project;
109-
}
11074
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
source.. = src/
22
output.. = target/classes/
33
bin.includes = META-INF/,\
4-
.
4+
.,\
5+
projects/
56
javacSource=1.7
67
javacTarget=1.7
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* Copyright 2016 Google Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.tools.eclipse.appengine.localserver.server;
18+
19+
import static org.junit.Assert.assertEquals;
20+
import static org.junit.Assert.assertNotNull;
21+
import static org.junit.Assert.assertTrue;
22+
23+
import com.google.cloud.tools.eclipse.test.util.project.ProjectUtils;
24+
import java.io.File;
25+
import java.io.IOException;
26+
import java.util.List;
27+
import org.eclipse.core.resources.IProject;
28+
import org.eclipse.core.runtime.CoreException;
29+
import org.eclipse.core.runtime.IPath;
30+
import org.eclipse.wst.server.core.IModule;
31+
import org.eclipse.wst.server.core.IServer;
32+
import org.eclipse.wst.server.core.IServerType;
33+
import org.eclipse.wst.server.core.IServerWorkingCopy;
34+
import org.eclipse.wst.server.core.ServerCore;
35+
import org.eclipse.wst.server.core.ServerUtil;
36+
import org.junit.After;
37+
import org.junit.Assume;
38+
import org.junit.Before;
39+
import org.junit.Test;
40+
41+
/** Verify that the server properly published submodule projects */
42+
public class LocalAppEnginePublishOperationTest {
43+
private List<IProject> projects;
44+
private IProject serverProject;
45+
private IProject sharedProject;
46+
private IModule serverModule;
47+
private IModule sharedModule;
48+
private IServer server;
49+
50+
@Before
51+
public void setUp() throws IOException, CoreException {
52+
Assume.assumeFalse("This test is flakey on travis and needs to be de-flaked",
53+
Boolean.parseBoolean(System.getenv("TRAVIS")));
54+
55+
projects = ProjectUtils.importProjects(getClass(), "projects/test-submodules.zip", null);
56+
assertEquals(2, projects.size());
57+
assertTrue("sox-server".equals(projects.get(0).getName())
58+
|| "sox-server".equals(projects.get(1).getName()));
59+
assertTrue("sox-shared".equals(projects.get(1).getName())
60+
|| "sox-shared".equals(projects.get(0).getName()));
61+
serverProject = projects.get("sox-server".equals(projects.get(0).getName()) ? 0 : 1);
62+
assertNotNull(serverProject);
63+
sharedProject = projects.get("sox-shared".equals(projects.get(0).getName()) ? 0 : 1);
64+
assertNotNull(sharedProject);
65+
66+
assertTrue(serverProject.getFile("bin/sox/server/GreetingServiceImpl.class").exists());
67+
assertTrue(sharedProject.getFile("bin/sox/shared/GreetingService.class").exists());
68+
69+
serverModule = ServerUtil.getModule(serverProject);
70+
assertNotNull(serverModule);
71+
sharedModule = ServerUtil.getModule(sharedProject);
72+
assertNotNull(sharedModule);
73+
}
74+
75+
@After
76+
public void tearDown() throws CoreException {
77+
if (projects != null) {
78+
for (IProject project : projects) {
79+
project.delete(true, null);
80+
}
81+
}
82+
if (server != null) {
83+
server.delete();
84+
}
85+
}
86+
87+
/**
88+
* Verify that multi-web-module works.
89+
*/
90+
@Test
91+
public void testPublishingSubmodules() throws IOException, CoreException {
92+
IServerType serverType =
93+
ServerCore.findServerType("com.google.cloud.tools.eclipse.appengine.standard.server");
94+
IServerWorkingCopy serverWorkingCopy =
95+
serverType.createServer(getClass().getName(), null, null);
96+
serverWorkingCopy.modifyModules(new IModule[] {serverModule}, null, null);
97+
server = serverWorkingCopy.saveAll(true, null);
98+
assertTrue(server.canPublish().isOK());
99+
assertTrue("publish failed", server.publish(IServer.PUBLISH_CLEAN, null).isOK());
100+
101+
LocalAppEngineServerBehaviour serverBehaviour =
102+
server.getAdapter(LocalAppEngineServerBehaviour.class);
103+
assertNotNull(serverBehaviour);
104+
105+
// now verify the result
106+
IPath deployDirectory = serverBehaviour.getModuleDeployDirectory(serverModule);
107+
File publishedModule = deployDirectory.toFile();
108+
assertTrue(publishedModule.isDirectory());
109+
File webInf = new File(publishedModule, "WEB-INF");
110+
assertTrue(webInf.isDirectory());
111+
112+
assertTrue(new File(webInf, "appengine-web.xml").isFile());
113+
assertTrue(new File(webInf, "web.xml").isFile());
114+
assertTrue(new File(webInf, "classes/sox/server/GreetingServiceImpl.class").isFile());
115+
assertTrue(new File(webInf, "lib/servlet-2.5.jar").isFile());
116+
assertTrue(new File(webInf, "lib/sox-shared.jar").isFile());
117+
}
118+
}

plugins/com.google.cloud.tools.eclipse.appengine.localserver/META-INF/MANIFEST.MF

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Export-Package: com.google.cloud.tools.eclipse.appengine.localserver.server
3838
Import-Package: com.google.cloud.tools.eclipse.appengine.facets,
3939
com.google.cloud.tools.eclipse.appengine.libraries.model,
4040
com.google.cloud.tools.eclipse.appengine.libraries.repository,
41+
com.google.cloud.tools.eclipse.jst.server.core,
4142
com.google.cloud.tools.eclipse.preferences,
4243
com.google.cloud.tools.eclipse.preferences.areas,
4344
com.google.cloud.tools.eclipse.sdk.ui,

0 commit comments

Comments
 (0)