Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .idea/dictionaries/bhale.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions .idea/runConfigurations/versions__JSON_.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions config/tomcat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,6 @@ redis_store:
database: 0
timeout: 2000
connection_pool_size: 2
geode_store:
version: 0.+
repository_root: "https://tomcat-javabuildpack-spike.s3.amazonaws.com/geode-store"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem like a production version of this bucket URI. Also, for performance reasons, buckets hosted on S3 should probably exposed via CloudFront.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the process of find out where i can place the tar

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the code really is Geode, and is all backed by an ASL repository, we could host it for you.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all but one jar is from Geode

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is that one file from? Is it GemFire branded?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the jar is called pcc-client-auth

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it'll need to be a public repository with a permissive license for us to host it. This goes back to the fact that the CFF needs to take a special exception for US export compliance that can only be satisfied by 100% open source code.

8 changes: 5 additions & 3 deletions lib/java_buildpack/container/tomcat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@

require 'java_buildpack/component/modular_component'
require 'java_buildpack/container'
require 'java_buildpack/container/tomcat/tomcat_access_logging_support'
require 'java_buildpack/container/tomcat/tomcat_external_configuration'
require 'java_buildpack/container/tomcat/tomcat_geode_store'
require 'java_buildpack/container/tomcat/tomcat_insight_support'
require 'java_buildpack/container/tomcat/tomcat_instance'
require 'java_buildpack/container/tomcat/tomcat_external_configuration'
require 'java_buildpack/container/tomcat/tomcat_lifecycle_support'
require 'java_buildpack/container/tomcat/tomcat_logging_support'
require 'java_buildpack/container/tomcat/tomcat_access_logging_support'
require 'java_buildpack/container/tomcat/tomcat_redis_store'
require 'java_buildpack/util/java_main_utils'

Expand Down Expand Up @@ -50,9 +51,10 @@ def command
def sub_components(context)
components = [
TomcatInstance.new(sub_configuration_context(context, 'tomcat')),
TomcatAccessLoggingSupport.new(sub_configuration_context(context, 'access_logging_support')),
TomcatGeodeStore.new(sub_configuration_context(context, 'geode_store')),
TomcatLifecycleSupport.new(sub_configuration_context(context, 'lifecycle_support')),
TomcatLoggingSupport.new(sub_configuration_context(context, 'logging_support')),
TomcatAccessLoggingSupport.new(sub_configuration_context(context, 'access_logging_support')),
TomcatRedisStore.new(sub_configuration_context(context, 'redis_store')),
TomcatInsightSupport.new(context)
]
Expand Down
176 changes: 176 additions & 0 deletions lib/java_buildpack/container/tomcat/tomcat_geode_store.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# Cloud Foundry Java Buildpack
# Copyright 2013-2017 the original author or authors.
#
# Licensed 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.

require 'java_buildpack/component/versioned_dependency_component'
require 'java_buildpack/container'
require 'java_buildpack/container/tomcat/tomcat_utils'
require 'java_buildpack/logging/logger_factory'

module JavaBuildpack
module Container

# Encapsulates the detect, compile, and release functionality for Tomcat Redis support.
class TomcatGeodeStore < JavaBuildpack::Component::VersionedDependencyComponent
include JavaBuildpack::Container

# (see JavaBuildpack::Component::BaseComponent#compile)
def compile
return unless supports?
download_tar(false, tomcat_lib, tar_name)
mutate_context
mutate_server
create_cache_client_xml
end

# (see JavaBuildpack::Component::BaseComponent#release)
def release
return unless supports?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need for this (that's why you don't see it anywhere else). release isn't called unless detect first confirms its use.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when I tried to remove the check for supports i get the following

ERROR Release failed with exception #<NoMethodError: undefined method `[]' for nil:NilClass>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Under what circumstances, tests? Or in actual usage?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it fails on actual usage when attempting to compile.

@nebhale nebhale Jun 5, 2017

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, you're right. I forgot that 1ModularComponents behave differently with respect to their modules. You can disregard these comments.

credentials = @application.services.find_service(FILTER)['credentials']
user = credentials[KEY_USERS].find { |u| u['username'] == 'cluster_operator' }

@droplet.java_opts.add_system_property 'gemfire.security-username', 'cluster_operator'
@droplet.java_opts.add_system_property 'gemfire.security-password', user['password']
@droplet.java_opts.add_system_property 'gemfire.security-client-auth-init',
'io.pivotal.cloudcache.ClientAuthInitialize.create'
end

protected

# (see JavaBuildpack::Component::VersionedDependencyComponent#supports?)
def supports?
@application.services.one_service? FILTER, KEY_LOCATORS, KEY_USERS
end

private

FILTER = /session-replication/
KEY_LOCATORS = 'locators'.freeze
KEY_USERS = 'users'.freeze

SESSION_MANAGER_CLASS_NAME = 'org.apache.geode.modules.session.catalina.Tomcat8DeltaSessionManager'.freeze
REGION_ATTRIBUTES_ID = 'PARTITION_REDUNDANT_HEAP_LRU'.freeze
CACHE_CLIENT_LISTENER_CLASS_NAME =
'org.apache.geode.modules.session.catalina.ClientServerCacheLifecycleListener'.freeze
SCHEMA_URL = 'http://geode.apache.org/schema/cache'.freeze
SCHEMA_INSTANCE_URL = 'http://www.w3.org/2001/XMLSchema-instance'.freeze
SCHEMA_LOCATION = 'http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd'.freeze
LOCATOR_REGEXP = Regexp.new('([^\\[]+)\\[([^\\]]+)\\]').freeze
FUNCTION_SERVICE_CLASS_NAMES = [
'org.apache.geode.modules.util.CreateRegionFunction',
'org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction',
'org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction',
'org.apache.geode.modules.util.RegionSizeFunction'
].freeze

private_constant :FILTER, :KEY_LOCATORS, :KEY_USERS, :SESSION_MANAGER_CLASS_NAME, :REGION_ATTRIBUTES_ID,
:CACHE_CLIENT_LISTENER_CLASS_NAME, :SCHEMA_URL, :SCHEMA_INSTANCE_URL, :SCHEMA_LOCATION,
:LOCATOR_REGEXP, :FUNCTION_SERVICE_CLASS_NAMES

def add_client_cache(document)
client_cache = document.add_element 'client-cache',
'xmlns' => SCHEMA_URL,
'xmlns:xsi' => SCHEMA_INSTANCE_URL,
'xsi:schemaLocation' => SCHEMA_LOCATION,
'version' => '1.0'

add_pool client_cache
add_function_service client_cache
end

def add_functions(function_service)
FUNCTION_SERVICE_CLASS_NAMES.each do |function_class_name|
function = function_service.add_element 'function'
class_name = function.add_element 'class-name'
class_name.add_text(function_class_name)
end
end

def add_function_service(client_cache)
function_service = client_cache.add_element 'function-service'
add_functions function_service
end

def add_listener(server)
server.add_element 'Listener',
'className' => CACHE_CLIENT_LISTENER_CLASS_NAME
end

def add_locators(pool)
service = @application.services.find_service FILTER
service['credentials']['locators'].each do |locator|
match_info = LOCATOR_REGEXP.match(locator)
pool.add_element 'locator',
'host' => match_info[1],
'port' => match_info[2]
end
end

def add_manager(context)
context.add_element 'Manager',
'className' => SESSION_MANAGER_CLASS_NAME,
'enableLocalCache' => 'true',
'regionAttributesId' => REGION_ATTRIBUTES_ID
end

def add_pool(client_cache)
pool = client_cache.add_element 'pool',
'name' => 'sessions',
'subscription-enabled' => 'true'
add_locators pool
end

def cache_client_xml
'cache-client.xml'
end

def cache_client_xml_path
@droplet.sandbox + 'conf' + cache_client_xml
end

def create_cache_client_xml
document = REXML::Document.new('<?xml version="1.0" encoding="UTF-8"?>')
add_client_cache document
write_xml cache_client_xml_path, document
end

def mutate_context
puts ' Adding Geode-based Session Replication'

document = read_xml context_xml
context = REXML::XPath.match(document, '/Context').first

add_manager context

write_xml context_xml, document
end

def mutate_server
document = read_xml server_xml

server = REXML::XPath.match(document, '/Server').first

add_listener server

write_xml server_xml, document
end

def tar_name
"geode-store-#{@version}.tar.gz"
end

end

end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version='1.0' encoding='utf-8'?>
<!--
~ Copyright 2013-2017 the original author or authors.
~
~ Licensed 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.
-->

<Context allowLinking='true'>
</Context>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version='1.0' encoding='utf-8'?>
<!--
~ Copyright 2013-2017 the original author or authors.
~
~ Licensed 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.
-->
<Server port='-1'>

<Service name='Catalina'>
<Connector port='${http.port}' bindOnInit='false' connectionTimeout='20000'/>

<Engine defaultHost='localhost' name='Catalina'>
<Valve className='org.apache.catalina.valves.RemoteIpValve' protocolHeader='x-forwarded-proto'/>
<Valve className='com.gopivotal.cloudfoundry.tomcat.logging.access.CloudFoundryAccessLoggingValve'
pattern='[ACCESS] %{org.apache.catalina.AccessLog.RemoteAddr}r %l %t %D %F %B %S vcap_request_id:%{X-Vcap-Request-Id}i'
enabled='${access.logging.enabled}'/>
<Host name='localhost'
failCtxIfServletStartFails='true'>
<Listener className='com.gopivotal.cloudfoundry.tomcat.lifecycle.ApplicationStartupFailureDetectingLifecycleListener'/>
</Host>
</Engine>
</Service>

</Server>
Empty file.
21 changes: 21 additions & 0 deletions spec/fixtures/container_tomcat_geode_store_cache_client_after.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
<client-cache xmlns='http://geode.apache.org/schema/cache' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd' version='1.0'>
<pool name='sessions' subscription-enabled='true'>
<locator host='some-locator' port='some-port'/>
<locator host='some-other-locator' port='some-other-port'/>
</pool>
<function-service>
<function>
<class-name>org.apache.geode.modules.util.CreateRegionFunction</class-name>
</function>
<function>
<class-name>org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction</class-name>
</function>
<function>
<class-name>org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction</class-name>
</function>
<function>
<class-name>org.apache.geode.modules.util.RegionSizeFunction</class-name>
</function>
</function-service>
</client-cache>
19 changes: 19 additions & 0 deletions spec/fixtures/container_tomcat_geode_store_context_after.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
~ Copyright 2013-2017 the original author or authors.
~
~ Licensed 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.
-->
<Context allowLinking='true'>
<Manager className='org.apache.geode.modules.session.catalina.Tomcat8DeltaSessionManager' enableLocalCache='true' regionAttributesId='PARTITION_REDUNDANT_HEAP_LRU'/>
</Context>
29 changes: 29 additions & 0 deletions spec/fixtures/container_tomcat_geode_store_server_after.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
~ Copyright 2013-2017 the original author or authors.
~
~ Licensed 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.
-->
<Server port='-1'>
<Service name='Catalina'>
<Connector port='${http.port}' bindOnInit='false' connectionTimeout='20000'/>
<Engine defaultHost='localhost' name='Catalina'>
<Valve className='org.apache.catalina.valves.RemoteIpValve' protocolHeader='x-forwarded-proto'/>
<Valve className='com.gopivotal.cloudfoundry.tomcat.logging.access.CloudFoundryAccessLoggingValve' pattern='[ACCESS] %{org.apache.catalina.AccessLog.RemoteAddr}r %l %t %D %F %B %S vcap_request_id:%{X-Vcap-Request-Id}i' enabled='${access.logging.enabled}'/>
<Host name='localhost' failCtxIfServletStartFails='true'>
<Listener className='com.gopivotal.cloudfoundry.tomcat.lifecycle.ApplicationStartupFailureDetectingLifecycleListener'/>
</Host>
</Engine>
</Service>
<Listener className='org.apache.geode.modules.session.catalina.ClientServerCacheLifecycleListener'/>
</Server>
Empty file.
Binary file added spec/fixtures/stub-geode-store.tar
Binary file not shown.
Loading