diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/pom.xml b/components/registry/org.wso2.carbon.registry.caching.invalidator/pom.xml new file mode 100644 index 000000000..13b2e8dc5 --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/pom.xml @@ -0,0 +1,69 @@ + + + + + org.wso2.carbon.registry + registry + 4.4.2-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.registry.caching.invalidator + bundle + WSO2 Carbon - Caching Invalidator + OSGi Bundle for the Cache invalidation for Carbon + http://wso2.org + + + + org.wso2.carbon + org.wso2.carbon.core + + + org.wso2.carbon + org.wso2.carbon.utils + + + org.wso2.carbon + javax.cache.wso2 + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.apache.geronimo.specs.wso2 + geronimo-jms_1.1_spec + + + + + + + org.apache.felix + maven-scr-plugin + + + org.apache.felix + maven-bundle-plugin + true + + + ${project.artifactId} + ${project.artifactId} + + org.wso2.carbon.registry.caching.invalidator.* + + + !org.wso2.carbon.registry.caching.invalidator.*, + javax.jms.* + + * + + + + + + + diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/CacheInvalidationException.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/CacheInvalidationException.java new file mode 100644 index 000000000..2aa87294c --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/CacheInvalidationException.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.connection; + +public class CacheInvalidationException extends Exception { + public CacheInvalidationException(String message, Throwable cause) { + super(message,cause); + } + + public CacheInvalidationException(String message) { + super(message); + } +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/InvalidNotification.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/InvalidNotification.java new file mode 100644 index 000000000..d82aed058 --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/InvalidNotification.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.connection; + +import java.util.Properties; + +public interface InvalidNotification { + + public void createConnection(Properties config); + + public void closeConnection(); + + public void publish(Object message); + + public void subscribe(); +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/InvalidationConnectionFactory.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/InvalidationConnectionFactory.java new file mode 100644 index 000000000..2b4620e74 --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/InvalidationConnectionFactory.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.connection; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.registry.caching.invalidator.impl.ConfigurationManager; +import org.wso2.carbon.registry.caching.invalidator.internal.CacheInvalidationDataHolder; + +import java.util.Properties; + +public class InvalidationConnectionFactory { + private static final Log log = LogFactory.getLog(InvalidationConnectionFactory.class); + + public static void createMessageBrokerConnection() throws CacheInvalidationException { + Properties properties = ConfigurationManager.getCacheConfiguration(); + if (properties.containsKey("class.CacheInvalidationClass")) { + InvalidNotification connection = (InvalidNotification) getObject(properties.getProperty("class.CacheInvalidationClass")); + if (connection != null) { + connection.createConnection(properties); + CacheInvalidationDataHolder.setConnection(connection); + } else { + log.warn("Error while initializing message, Global cache invalidation will not work"); + } + } + } + + private static Object getObject(String className) throws CacheInvalidationException { + try { + Class factoryClass = Class.forName(className); + return factoryClass.newInstance(); + } catch (ClassNotFoundException e) { + throw new CacheInvalidationException("Class " + className + " not found ", e); + } catch (IllegalAccessException e) { + throw new CacheInvalidationException("Class not be accessed ", e); + } catch (InstantiationException e) { + throw new CacheInvalidationException("Class not be instantiated ", e); + } + } +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/JMSNotification.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/JMSNotification.java new file mode 100644 index 000000000..551f53b5d --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/connection/JMSNotification.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.connection; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.registry.caching.invalidator.impl.ConfigurationManager; +import org.wso2.carbon.registry.caching.invalidator.impl.GlobalCacheInvalidationEvent; +import org.wso2.carbon.registry.caching.invalidator.internal.CacheInvalidationDataHolder; +import org.wso2.carbon.context.PrivilegedCarbonContext; + +import javax.cache.CacheManager; +import javax.cache.Caching; +import javax.jms.BytesMessage; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TopicSession; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Properties; + +public class JMSNotification implements InvalidNotification, MessageListener{ + + // Setup the pub/sub connection, session + // Send the msg (byte stream) + private static Connection connection = null; + + private static Destination destination = null; + + private static final Log log = LogFactory.getLog(JMSNotification.class); + @Override + public void createConnection(Properties config) { + try { + Properties props = new Properties(); + props.put(Context.INITIAL_CONTEXT_FACTORY, config.getProperty("initialContextFactory")); + props.put(Context.PROVIDER_URL, config.getProperty("providerUrl")); + props.put(Context.SECURITY_PRINCIPAL, config.getProperty("securityPrincipal")); + props.put(Context.SECURITY_CREDENTIALS, config.getProperty("securityCredentials")); + props.put("topic.cacheInvalidateTopic", config.getProperty("cacheInvalidateTopic")); + InitialContext jndi = new InitialContext(props); + ConnectionFactory connectionFactory = (ConnectionFactory) jndi.lookup("ConnectionFactory"); + destination = (Destination)jndi.lookup("cacheInvalidateTopic"); + + connection = connectionFactory.createConnection(config.getProperty("securityPrincipal"), + config.getProperty("securityCredentials")); + connection.start(); + } catch (NamingException | JMSException e) { + log.error("Global cache invalidation: Error message broker initialization", e); + } + } + + @Override + public void closeConnection() { + if (connection != null) { + try { + connection.close(); + } catch (JMSException e) { + log.error("Global cache invalidation: Error in closing connection", e); + } + } + } + + + @Override + public void publish(Object message) { + Session pubSession = null; + try { + if (connection != null) { + pubSession = connection.createSession(false, TopicSession.AUTO_ACKNOWLEDGE); + MessageProducer publisher = pubSession.createProducer(destination); + BytesMessage bytesMessage = pubSession.createBytesMessage(); + bytesMessage.writeBytes((byte[]) message); + publisher.send(bytesMessage); + } + } catch (JMSException e) { + log.error("Global cache invalidation: Error in publishing the message", e); + } finally { + if (pubSession != null) { + try { + pubSession.close(); + } catch (JMSException e) { + log.error("Global cache invalidation: Error in publishing the message", e); } + } + } + } + + @Override + public void subscribe() { + try { + Session subSession = connection.createSession(false, TopicSession.AUTO_ACKNOWLEDGE); + MessageConsumer messageConsumer = subSession.createConsumer(destination); + messageConsumer.setMessageListener(this); + connection.start(); + log.info("Global cache invalidation is online"); + } catch (JMSException e) { + log.error("Global cache invalidation: Error in subscribing to topic", e); + } + } + + @Override + public void onMessage(Message message) { + BytesMessage bytesMessage = (BytesMessage) message; + byte[] data; + try { + data = new byte[(int) bytesMessage.getBodyLength()]; + for (int i = 0; i < (int) bytesMessage.getBodyLength(); i++) { + data[i] = bytesMessage.readByte(); + } + log.debug("Cache invalidation message received: " + new String(data)); + } catch (JMSException jmsException) { + log.error("Error while reading the received message", jmsException); + return; + } + + boolean isCoordinator = false; + if (CacheInvalidationDataHolder.getConfigContext() != null) { + isCoordinator = CacheInvalidationDataHolder.getConfigContext().getAxisConfiguration() + .getClusteringAgent().isCoordinator(); + } + if (isCoordinator) { + PrivilegedCarbonContext.startTenantFlow(); + try { + log.debug("Global cache invalidation: deserializing data to object"); + GlobalCacheInvalidationEvent event = (GlobalCacheInvalidationEvent) deserialize(data); + log.debug("Global cache invalidation: deserializing complete"); + if (!ConfigurationManager.getSentMsgBuffer().contains(event.getUuid().trim())) { // Ignore own messages + PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(event.getTenantId(), true); + CacheManager cacheManager = Caching.getCacheManagerFactory().getCacheManager(event.getCacheManagerName()); + if (cacheManager != null) { + if (cacheManager.getCache(event.getCacheName()) != null) { + cacheManager.getCache(event.getCacheName()).remove(event.getCacheKey()); + log.debug("Global cache invalidated: " + event.getCacheKey()); + } else { + log.error("Global cache invalidation: error cache is null"); + } + } else { + log.error("Global cache invalidation: error cache manager is null"); + } + } else { + // To resolve future performance issues + ConfigurationManager.getSentMsgBuffer().remove(event.getUuid().trim()); + log.debug("Global cache invalidation: own message ignored"); + } + } catch (Exception e) { + log.error("Global cache invalidation: error local cache update", e); + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + } + } + + private Object deserialize(byte[] bytes) throws IOException, ClassNotFoundException { + ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); + ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); + return objectInputStream.readObject(); + } +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/CacheInvalidationPublisher.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/CacheInvalidationPublisher.java new file mode 100644 index 000000000..519c00acb --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/CacheInvalidationPublisher.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.caching.impl.CacheInvalidator; +import org.wso2.carbon.registry.caching.invalidator.connection.CacheInvalidationException; +import org.wso2.carbon.registry.caching.invalidator.connection.InvalidationConnectionFactory; +import org.wso2.carbon.registry.caching.invalidator.internal.CacheInvalidationDataHolder; +import org.wso2.carbon.registry.core.utils.UUIDGenerator; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * Global cache invalidation publisher implements org.wso2.carbon.caching.impl.CacheInvalidator interface + */ +public class CacheInvalidationPublisher implements CacheInvalidator { + private static final Log log = LogFactory.getLog(CacheInvalidationPublisher.class); + + @Override + public void invalidateCache(int tenantId, String cacheManagerName, String cacheName, Serializable cacheKey) { + log.debug("Global cache invalidation: initializing the connection"); + if (CacheInvalidationDataHolder.getConnection() == null) { + ConfigurationManager.init(); + } + //Converting data to json string + GlobalCacheInvalidationEvent event = new GlobalCacheInvalidationEvent(); + event.setTenantId(tenantId); + event.setCacheManagerName(cacheManagerName); + event.setCacheName(cacheName); + event.setCacheKey(cacheKey); + String uuid = UUIDGenerator.generateUUID(); + event.setUuid(uuid); + byte data[]; + try { + log.debug("Global cache invalidation: converting serializable object to byte stream."); + data = serialize(event); + log.debug("Global cache invalidation: converting data to byte stream complete."); + } catch (IOException e) { + log.error("Global cache invalidation: Error while converting data to byte stream", e); + return; + } + + if (CacheInvalidationDataHolder.getConnection() != null) { + CacheInvalidationDataHolder.getConnection().publish(data); + } else { + try { + InvalidationConnectionFactory.createMessageBrokerConnection(); + CacheInvalidationDataHolder.getConnection().publish(data); + } catch (CacheInvalidationException e) { + log.error("Error while publishing data, connection couldn't establish", e); + } + } + } + + private byte[] serialize(Object obj) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); + objectOutputStream.writeObject(obj); + return byteArrayOutputStream.toByteArray(); + } +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/CacheInvalidationSubscriber.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/CacheInvalidationSubscriber.java new file mode 100644 index 000000000..58883ff2e --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/CacheInvalidationSubscriber.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.impl; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.core.clustering.api.CoordinatedActivity; +import org.wso2.carbon.registry.caching.invalidator.connection.CacheInvalidationException; +import org.wso2.carbon.registry.caching.invalidator.connection.InvalidationConnectionFactory; +import org.wso2.carbon.registry.caching.invalidator.internal.CacheInvalidationDataHolder; + +/** + * Global cache invalidation subscriber implements org.wso2.carbon.core.clustering.api.CoordinatedActivity interface + */ +public class CacheInvalidationSubscriber implements CoordinatedActivity { + private static final Log log = LogFactory.getLog(CacheInvalidationSubscriber.class); + + public CacheInvalidationSubscriber() { + if (CacheInvalidationDataHolder.getConfigContext() != null && + CacheInvalidationDataHolder.getConfigContext().getAxisConfiguration().getClusteringAgent() != null) { + boolean isCoordinator = CacheInvalidationDataHolder.getConfigContext().getAxisConfiguration() + .getClusteringAgent().isCoordinator(); + if (isCoordinator && !ConfigurationManager.isSubscribed()) { + if (CacheInvalidationDataHolder.getConnection() != null) { + CacheInvalidationDataHolder.getConnection().subscribe(); + ConfigurationManager.setSubscribed(true); + } else { + try { + InvalidationConnectionFactory.createMessageBrokerConnection(); + CacheInvalidationDataHolder.getConnection().subscribe(); + ConfigurationManager.setSubscribed(true); + } catch (CacheInvalidationException e) { + log.error("Error while subscribing to the queue, connection couldn't establish", e); + } + } + } + } + } + + @Override + public void execute() { + if(ConfigurationManager.init() && CacheInvalidationDataHolder.getConfigContext() != null) { + boolean isCoordinator = CacheInvalidationDataHolder.getConfigContext().getAxisConfiguration() + .getClusteringAgent().isCoordinator(); + if (isCoordinator && !ConfigurationManager.isSubscribed()) { + if (CacheInvalidationDataHolder.getConnection() != null) { + CacheInvalidationDataHolder.getConnection().subscribe(); + } else { + try { + InvalidationConnectionFactory.createMessageBrokerConnection(); + CacheInvalidationDataHolder.getConnection().subscribe(); + } catch (CacheInvalidationException e) { + log.error("Error while subscribing to the queue, connection couldn't establish", e); + return; + } + } + ConfigurationManager.setSubscribed(true); + } + if (!isCoordinator && ConfigurationManager.isSubscribed()) { + ConfigurationManager.setSubscribed(false); + } + } + } + +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/ConfigurationManager.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/ConfigurationManager.java new file mode 100644 index 000000000..e8d676250 --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/ConfigurationManager.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.utils.CarbonUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +/** + * Global cache invalidation configuration manager which extract configuration parameters from cache.xml + */ +public class ConfigurationManager { + private static final Log log = LogFactory.getLog(ConfigurationManager.class); + + private static boolean subscribed = false; + + private static boolean enabled = false; + + private static Properties cacheConfiguration = new Properties(); + + private static List sentMsgBuffer; + + public static boolean init(){ + String configFilePath = CarbonUtils.getCarbonHome() + File.separator + "repository" + + File.separator + "conf" + File.separator + "cache.properties"; + FileInputStream fileInputStream = null; + try{ + fileInputStream = new FileInputStream(configFilePath); + cacheConfiguration.load(fileInputStream); + + if(cacheConfiguration.containsKey("enabled")) { + enabled = Boolean.parseBoolean(cacheConfiguration.getProperty("enabled")); + } + + if(!enabled){ + log.info("Global cache invalidation is offline according to cache.properties configurations"); + } + + } catch (IOException ioException) { + log.error("Global cache invalidation : Error while reading cache.properties file", ioException); + } finally { + if (fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException ioException) { + log.error("Global cache invalidation : Error while reading cache.properties file", ioException); + } + } + } + return enabled; + } + + public static List getSentMsgBuffer() { + if(sentMsgBuffer == null){ + sentMsgBuffer = new ArrayList(); + } + return sentMsgBuffer; + } + + public static Properties getCacheConfiguration() { + return cacheConfiguration; + } + + public static boolean isSubscribed() { + return subscribed; + } + + public static void setSubscribed(boolean subscribed) { + ConfigurationManager.subscribed = subscribed; + } + + public static boolean isEnabled() { + return enabled; + } +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/GlobalCacheInvalidationEvent.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/GlobalCacheInvalidationEvent.java new file mode 100644 index 000000000..53bc55c66 --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/impl/GlobalCacheInvalidationEvent.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.impl; + +import java.io.Serializable; + +/** + * Global cache invalidation event serializable object which used to send the data to message broker + */ +public class GlobalCacheInvalidationEvent implements Serializable { + private int tenantId; + private String cacheManagerName; + private String cacheName; + private Serializable cacheKey; + private String uuid; + + public int getTenantId() { + return tenantId; + } + + public void setTenantId(int tenantId) { + this.tenantId = tenantId; + } + + public String getCacheManagerName() { + return cacheManagerName; + } + + public void setCacheManagerName(String cacheManagerName) { + this.cacheManagerName = cacheManagerName; + } + + public String getCacheName() { + return cacheName; + } + + public void setCacheName(String cacheName) { + this.cacheName = cacheName; + } + + public Serializable getCacheKey() { + return cacheKey; + } + + public void setCacheKey(Serializable cacheKey) { + this.cacheKey = cacheKey; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/internal/CacheInvalidationDataHolder.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/internal/CacheInvalidationDataHolder.java new file mode 100644 index 000000000..050724823 --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/internal/CacheInvalidationDataHolder.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.internal; + +import org.apache.axis2.context.ConfigurationContext; +import org.wso2.carbon.registry.caching.invalidator.connection.InvalidNotification; + +/** + * Cache Invalidation data holder + */ +public class CacheInvalidationDataHolder { + private static ConfigurationContext configContext; + private static InvalidNotification connection; + + public static void setConfigContext(ConfigurationContext configContext) { + CacheInvalidationDataHolder.configContext = configContext; + } + + public static ConfigurationContext getConfigContext() { + return configContext; + } + + public static void setConnection(InvalidNotification connection) { + CacheInvalidationDataHolder.connection = connection; + } + + public static InvalidNotification getConnection() { + return connection; + } +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/internal/CacheInvalidationServiceComponent.java b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/internal/CacheInvalidationServiceComponent.java new file mode 100644 index 000000000..65f9bc7c8 --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/java/org/wso2/carbon/registry/caching/invalidator/internal/CacheInvalidationServiceComponent.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * 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. + */ +package org.wso2.carbon.registry.caching.invalidator.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.caching.impl.CacheInvalidator; +import org.wso2.carbon.registry.caching.invalidator.connection.InvalidationConnectionFactory; +import org.wso2.carbon.registry.caching.invalidator.impl.CacheInvalidationPublisher; +import org.wso2.carbon.registry.caching.invalidator.impl.CacheInvalidationSubscriber; +import org.wso2.carbon.registry.caching.invalidator.impl.ConfigurationManager; +import org.wso2.carbon.core.clustering.api.CoordinatedActivity; +import org.wso2.carbon.utils.ConfigurationContextService; + +/** + * @scr.component name="CacheInvalidationServiceComponent" immediate="true" + * @scr.reference name="configuration.context.service" + * interface="org.wso2.carbon.utils.ConfigurationContextService" cardinality="1..1" + * policy="dynamic" bind="setConfigurationContextService" unbind="unsetConfigurationContextService" + */ + +public class CacheInvalidationServiceComponent { + private static Log log = LogFactory.getLog(CacheInvalidationServiceComponent.class); + ServiceRegistration serviceRegistration; + CacheInvalidationSubscriber subscriber; + CacheInvalidationPublisher publisher; + + protected void activate(ComponentContext ctxt) { + log.debug("Cache Invalidation Service activation started"); + try { + if(ConfigurationManager.init()) { + InvalidationConnectionFactory.createMessageBrokerConnection(); + subscriber = new CacheInvalidationSubscriber(); + publisher = new CacheInvalidationPublisher(); + serviceRegistration = ctxt.getBundleContext().registerService(CacheInvalidator.class, publisher, null); + serviceRegistration = ctxt.getBundleContext().registerService(CoordinatedActivity.class, subscriber, null); + } + } catch (Exception e) { + String msg = "Failed to initialize the Cache Invalidation Service"; + log.error(msg, e); + } + } + + protected void deactivate(ComponentContext ctxt) { + log.debug("Cache Invalidation Service stopped"); + try{ + if(serviceRegistration != null) { + serviceRegistration.unregister(); + } + }catch (Exception e){ + String msg = "Failed to Stop the Cache Invalidation Service"; + log.error(msg, e); + } + } + + protected void setConfigurationContextService(ConfigurationContextService contextService) { + CacheInvalidationDataHolder.setConfigContext(contextService.getServerConfigContext()); + } + + protected void unsetConfigurationContextService(ConfigurationContextService contextService) { + CacheInvalidationDataHolder.setConfigContext(null); + } +} diff --git a/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/resources/cache.properties b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/resources/cache.properties new file mode 100644 index 000000000..10359da14 --- /dev/null +++ b/components/registry/org.wso2.carbon.registry.caching.invalidator/src/main/resources/cache.properties @@ -0,0 +1,22 @@ + +enabled=false +class.CacheInvalidationClass=org.wso2.carbon.registry.caching.invalidator.connection.JMSNotification +initialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory +providerUrl=tcp://localhost:61616 +securityPrincipal=guest +securityCredentials=guest +cacheInvalidateTopic=GlobalCacheInvalidation \ No newline at end of file diff --git a/components/registry/org.wso2.carbon.registry.indexing/src/main/java/org/wso2/carbon/registry/indexing/service/ContentBasedSearchService.java b/components/registry/org.wso2.carbon.registry.indexing/src/main/java/org/wso2/carbon/registry/indexing/service/ContentBasedSearchService.java index a98ff8f3b..5844ff1e1 100755 --- a/components/registry/org.wso2.carbon.registry.indexing/src/main/java/org/wso2/carbon/registry/indexing/service/ContentBasedSearchService.java +++ b/components/registry/org.wso2.carbon.registry.indexing/src/main/java/org/wso2/carbon/registry/indexing/service/ContentBasedSearchService.java @@ -27,6 +27,7 @@ import org.wso2.carbon.registry.common.ResourceData; import org.wso2.carbon.registry.common.services.RegistryAbstractAdmin; import org.wso2.carbon.registry.common.utils.CommonUtil; +import org.wso2.carbon.registry.common.utils.UserUtil; import org.wso2.carbon.registry.core.ActionConstants; import org.wso2.carbon.registry.core.Collection; import org.wso2.carbon.registry.core.RegistryConstants; @@ -322,6 +323,21 @@ private ResourceData loadResourceByPath(UserRegistry registry, String path) thro resourceData.setCreatedOn(createdDateTime); CommonUtil.populateAverageStars(resourceData); + String user = child.getProperty("registry.user"); + + if (registry.getUserName().equals(user)) { + resourceData.setPutAllowed(true); + resourceData.setDeleteAllowed(true); + resourceData.setGetAllowed(true); + } else { + resourceData.setPutAllowed( + UserUtil.isPutAllowed(registry.getUserName(), path, registry)); + resourceData.setDeleteAllowed( + UserUtil.isDeleteAllowed(registry.getUserName(), path, registry)); + resourceData.setGetAllowed( + UserUtil.isGetAllowed(registry.getUserName(), path, registry)); + } + child.discard(); return resourceData; diff --git a/components/registry/pom.xml b/components/registry/pom.xml index 098ef2ce7..b407e69f9 100644 --- a/components/registry/pom.xml +++ b/components/registry/pom.xml @@ -70,6 +70,7 @@ org.wso2.carbon.registry.cmis org.wso2.carbon.registry.metadata org.wso2.carbon.registry.deployment.synchronizer + org.wso2.carbon.registry.caching.invalidator diff --git a/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.feature/pom.xml b/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.feature/pom.xml new file mode 100644 index 000000000..23e12377e --- /dev/null +++ b/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.feature/pom.xml @@ -0,0 +1,74 @@ + + + + + + + org.wso2.carbon.registry + caching-invalidator-feature + 4.4.2-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.registry.caching.invalidator.feature + pom + WSO2 Carbon - Global Caching Invalidator Feature + http://wso2.org + This feature contains the bundles required for Global Cache invalidation for Carbon + + + + org.wso2.carbon.registry + org.wso2.carbon.registry.caching.invalidator.server.feature + zip + ${carbon.registry.version} + + + + + + + org.wso2.maven + carbon-p2-plugin + ${carbon.p2.plugin.version} + + + p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.registry.caching.invalidator.server + ../feature.properties + + + org.eclipse.equinox.p2.type.group:true + + + + org.wso2.carbon.registry:org.wso2.carbon.registry.caching.invalidator.server.feature + + + + + + + + + diff --git a/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.server.feature/pom.xml b/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.server.feature/pom.xml new file mode 100644 index 000000000..a248134a0 --- /dev/null +++ b/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.server.feature/pom.xml @@ -0,0 +1,104 @@ + + + + + + + org.wso2.carbon.registry + caching-invalidator-feature + 4.4.2-SNAPSHOT + ../pom.xml + + + 4.0.0 + org.wso2.carbon.registry.caching.invalidator.server.feature + pom + WSO2 Carbon - Global Caching Invalidator Server Feature + http://wso2.org + This feature contains the core bundles required for Global Cache invalidation for Carbon + + + + org.wso2.carbon.registry + org.wso2.carbon.registry.caching.invalidator + + + org.apache.geronimo.specs.wso2 + geronimo-jms_1.1_spec + + + + + + + maven-resources-plugin + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + conf/cache.properties + p2.inf + + + + + + + + + org.wso2.maven + carbon-p2-plugin + ${carbon.p2.plugin.version} + + + 4-p2-feature-generation + package + + p2-feature-gen + + + org.wso2.carbon.registry.caching.invalidator.server + ../../etc/feature.properties + + + org.wso2.carbon.p2.category.type:server + org.eclipse.equinox.p2.type.group:false + + + + org.wso2.carbon.registry:org.wso2.carbon.registry.caching.invalidator + + + org.apache.geronimo.specs.wso2:geronimo-jms_1.1_spec + + + + + + + + + diff --git a/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.server.feature/src/main/resources/conf/cache.properties b/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.server.feature/src/main/resources/conf/cache.properties new file mode 100644 index 000000000..10359da14 --- /dev/null +++ b/features/caching-invalidator/org.wso2.carbon.registry.caching.invalidator.server.feature/src/main/resources/conf/cache.properties @@ -0,0 +1,22 @@ + +enabled=false +class.CacheInvalidationClass=org.wso2.carbon.registry.caching.invalidator.connection.JMSNotification +initialContextFactory=org.apache.activemq.jndi.ActiveMQInitialContextFactory +providerUrl=tcp://localhost:61616 +securityPrincipal=guest +securityCredentials=guest +cacheInvalidateTopic=GlobalCacheInvalidation \ No newline at end of file diff --git a/features/caching-invalidator/pom.xml b/features/caching-invalidator/pom.xml new file mode 100644 index 000000000..af0413307 --- /dev/null +++ b/features/caching-invalidator/pom.xml @@ -0,0 +1,39 @@ + + + + + + + org.wso2.carbon.registry + carbon-registry + 4.4.2-SNAPSHOT + ../../pom.xml + + + 4.0.0 + caching-invalidator-feature + pom + WSO2 Carbon - Global cache invalidation feature module + http://wso2.org + + + org.wso2.carbon.registry.caching.invalidator.server.feature + org.wso2.carbon.registry.caching.invalidator.feature + + + + diff --git a/pom.xml b/pom.xml index 0d004cdc0..7cdbd69ca 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ features/jcr features/uddi features/deployment-synchronizer + features/caching-invalidator @@ -354,6 +355,11 @@ + + org.wso2.carbon + javax.cache.wso2 + ${carbon.kernel.version} + org.wso2.carbon.commons org.wso2.carbon.user.mgt @@ -761,6 +767,11 @@ org.wso2.carbon.registry.deployment.synchronizer ${carbon.registry.version} + + org.wso2.carbon.registry + org.wso2.carbon.registry.caching.invalidator + ${carbon.registry.version} + @@ -1258,7 +1269,11 @@ oauth2-client ${amber.version} - + + org.apache.geronimo.specs.wso2 + geronimo-jms_1.1_spec + ${orbit.version.geronimo-jms_1.1_spec} + junit @@ -1442,6 +1457,9 @@ 4.4.0 [4.4.0, 4.5.0) + + 1.1.0.wso2v1 + 4.4.2-SNAPSHOT 1.0.1