BUG-2138: Create DistributedShardFrontend
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / utils / ClusterUtils.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.cluster.datastore.utils;
10
11 import akka.cluster.ddata.Key;
12 import akka.cluster.ddata.ORMap;
13 import akka.cluster.ddata.ORMapKey;
14 import java.util.Map;
15 import org.opendaylight.controller.cluster.access.concepts.MemberName;
16 import org.opendaylight.controller.cluster.datastore.config.PrefixShardConfiguration;
17 import org.opendaylight.controller.cluster.datastore.identifiers.ShardIdentifier;
18 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
21 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
22
23 /**
24  * Utils for encoding prefix shard name.
25  */
26 public class ClusterUtils {
27
28     // key for replicated configuration key
29     public static final Key<ORMap<PrefixShardConfiguration>> CONFIGURATION_KEY =
30             ORMapKey.create("prefix-shard-configuration");
31
32     public static ShardIdentifier getShardIdentifier(final MemberName memberName, final DOMDataTreeIdentifier prefix) {
33         final String type;
34         switch (prefix.getDatastoreType()) {
35             case OPERATIONAL:
36                 type = "operational";
37                 break;
38             case CONFIGURATION:
39                 type = "config";
40                 break;
41             default:
42                 type = prefix.getDatastoreType().name();
43         }
44
45         return ShardIdentifier.create(getCleanShardName(prefix.getRootIdentifier()), memberName, type);
46     }
47
48     /**
49      * Returns an encoded shard name based on the provided path that should doesn't contain characters that cannot be
50      * present in akka actor paths.
51      *
52      * @param path Path on which to base the shard name
53      * @return encoded name that doesn't contain characters that cannot be in actor path.
54      */
55     public static String getCleanShardName(final YangInstanceIdentifier path) {
56         if (path.isEmpty()) {
57             return "default";
58         }
59
60         final StringBuilder builder = new StringBuilder();
61         // TODO need a better mapping that includes namespace, but we'll need to cleanup the string beforehand
62         // we have to fight both javax and akka url path restrictions..
63         path.getPathArguments().forEach(p -> {
64             builder.append(p.getNodeType().getLocalName());
65             if (p instanceof NodeIdentifierWithPredicates) {
66                 builder.append("-key_");
67                 final Map<QName, Object> key = ((NodeIdentifierWithPredicates) p).getKeyValues();
68                 key.entrySet().forEach(e -> {
69                     builder.append(e.getKey().getLocalName());
70                     builder.append(e.getValue());
71                     builder.append("-");
72                 });
73                 builder.append("_");
74             }
75             builder.append("!");
76         });
77         return builder.toString();
78     }
79 }